UNPKG

tav-media

Version:

Cross platform media editing framework

98 lines (97 loc) 3.87 kB
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(); }); } }