tav-media
Version:
Cross platform media editing framework
98 lines (97 loc) • 3.87 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
/**
* 异步任务调度器
* @ignore
* @internal
*/
export class Dispatcher {
constructor() {
this.taskInQueue = Promise.resolve(1);
this.uniqueTaskCancelTokens = {};
this.tasks = [];
this.id = 0;
this.waitForNextTask = null;
this.run();
}
run() {
return __awaiter(this, void 0, void 0, function* () {
while (true) {
const task = this.tasks.shift();
if (!task) {
yield new Promise((resolve) => {
this.waitForNextTask = resolve;
});
continue;
}
yield task();
}
});
}
/**
* 设定超时
* @param time 超时时间 ms
*/
delay(time, cb) {
return new Promise((resolve) => setTimeout(() => {
cb();
resolve(undefined);
}, time));
}
/**
* 将任务加入队列,相同 uniqueId 的任务会被替换
* @param task 任务函数
* @param uniqueId 任务唯一标识,用于取消前置相同 uniqueId 的任务
*/
queue(task, uniqueId, timeout = 500) {
const id = this.id++;
const printTaskLog = false;
let cancelToken = null;
if (uniqueId) {
if (this.uniqueTaskCancelTokens[uniqueId]) {
this.uniqueTaskCancelTokens[uniqueId].cancel = true;
}
// 此处不能加 else, 每个任务应该有自己的 cancel token
// 否则可能会导致后置任务被取消
cancelToken = { cancel: false };
this.uniqueTaskCancelTokens[uniqueId] = cancelToken;
}
printTaskLog && console.log("task start", uniqueId, id);
return new Promise((res, rej) => {
const next = () => __awaiter(this, void 0, void 0, function* () {
if (cancelToken === null || cancelToken === void 0 ? void 0 : cancelToken.cancel) {
printTaskLog && console.log("task cancel", uniqueId, id);
return res(undefined);
}
let resolved = false;
const queued = Promise.race([
(() => __awaiter(this, void 0, void 0, function* () {
// wait for native calls
// await tav.webAssemblyQueue.exec(() => { }, null);
printTaskLog && console.log("task run", uniqueId, id);
const rt = yield task();
resolved = true;
printTaskLog && console.log("task end", uniqueId, id);
res(rt);
}))(),
this.delay(timeout, () => {
if (!resolved) {
printTaskLog && console.log("task timeout", uniqueId, id);
}
res(undefined);
}),
]);
return queued;
});
this.tasks.push(next);
this.waitForNextTask && this.waitForNextTask();
});
}
}