UNPKG

@planjs/utils

Version:

🔧 Common tools collection

104 lines (84 loc) 2.93 kB
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; import { prefSetTimeout, clearPrefTimeout } from '../function/pref-setTimeout'; import isObject from '../is/is-Object'; import asyncPool from '../promise/async-pool'; function asyncWorker(ctx) { var handlers = []; var ctrlMap = {}; function _onMessage(ev) { var messagePort = ev.ports[0]; if (messagePort) { handlers.forEach(function (handler) { Promise.resolve(handler(ev)).then(function (result) { messagePort.postMessage(result); }, function (err) { messagePort.postMessage(_defineProperty({}, asyncWorker.ERRKey, err)); }).catch(function (err) { console.log('[asyncWorker] onmessage error', err); }).finally(function () { messagePort.close(); }); }); } } function postMessage(payload, opts) { var timer = 0; var _MessageChannel = new MessageChannel(), port1 = _MessageChannel.port1, port2 = _MessageChannel.port2; var _doPost = function _doPost() { return new Promise(function (resolve, reject) { port1.onmessage = function (ev) { if (isObject(ev.data) && asyncWorker.ERRKey in ev.data) { reject(ev.data[asyncWorker.ERRKey]); } else { resolve(ev.data); } }; port1.onmessageerror = reject; ctx.postMessage(payload, [port2].concat(_toConsumableArray((opts === null || opts === void 0 ? void 0 : opts.transfer) || []))); if (opts !== null && opts !== void 0 && opts.timeout) { timer = prefSetTimeout(function () { reject(new Error('timeout')); }, opts.timeout); } }).finally(function () { port1.close(); timer && clearPrefTimeout(timer); }); }; // 启用并发控制 if (opts !== null && opts !== void 0 && opts.concurrent) { if (!ctrlMap[opts === null || opts === void 0 ? void 0 : opts.concurrent.key]) { ctrlMap[opts === null || opts === void 0 ? void 0 : opts.concurrent.key] = asyncPool({ maxConcurrency: opts.concurrent.max }); } return ctrlMap[opts === null || opts === void 0 ? void 0 : opts.concurrent.key].executor(_doPost); } return _doPost(); } /** * 只处理使用asyncWorker postMessage 发送的事件 * @param fn 返回值作为 postMessage 的返回结果 */ function register(fn) { handlers.push(fn); } function _listen() { ctx.addEventListener('message', _onMessage); } function setCtx(c) { ctx.removeEventListener('message', _onMessage); ctx = c; _listen(); } _listen(); return { setCtx: setCtx, postMessage: postMessage, register: register }; } asyncWorker.ERRKey = '__err__'; export default asyncWorker;