UNPKG

@gdjiami/jslib

Version:

Jiami FrontEnd helpers and Services

353 lines (298 loc) 8.07 kB
import _regeneratorRuntime from "@babel/runtime/regenerator"; /** * promise、异步操作相关的工具函数。 */ /** * 延迟指定毫秒 */ export function delay(ms) { return _regeneratorRuntime.async(function delay$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: return _context.abrupt("return", new Promise(function (res) { return setTimeout(res, ms); })); case 1: case "end": return _context.stop(); } } }); } /** * 增加超时机制的promise */ export function promiseWithTimeout(prom, timeout) { return _regeneratorRuntime.async(function promiseWithTimeout$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: return _context2.abrupt("return", new Promise(function (resolve, reject) { var resolved; var resolver = function resolver(val) { if (resolved) { return; } resolved = true; resolve(val); }; var rejector = function rejector(reason) { if (resolved) { return; } resolved = true; reject(reason); }; setTimeout(function () { return rejector(new Error('timeout')); }, timeout); prom(resolver, rejector); })); case 1: case "end": return _context2.stop(); } } }); } /** * 可重试的promise, 出现异常时进行重试 * @param prom * @param time 重试的次数 * @param duration 重试的间隔 */ export function retryablePromise(prom, time, duration) { var i, rt; return _regeneratorRuntime.async(function retryablePromise$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: if (time === void 0) { time = 1; } if (duration === void 0) { duration = 0; } i = 0; case 3: if (!(i < time)) { _context3.next = 21; break; } _context3.prev = 4; _context3.next = 7; return _regeneratorRuntime.awrap(prom()); case 7: rt = _context3.sent; return _context3.abrupt("return", rt); case 11: _context3.prev = 11; _context3.t0 = _context3["catch"](4); if (!(i < time)) { _context3.next = 17; break; } _context3.next = 16; return _regeneratorRuntime.awrap(delay(duration)); case 16: return _context3.abrupt("continue", 18); case 17: throw _context3.t0; case 18: i++; _context3.next = 3; break; case 21: return _context3.abrupt("return", undefined); case 22: case "end": return _context3.stop(); } } }, null, null, [[4, 11]]); } /** * 抽取出promise的Resolve和Reject函数, 可以在外部进行使用 * * @example * ```js * const { promise, reject, resolve } = extraPromise() * ``` */ export function extraPromise() { var resolve, reject, promise; return _regeneratorRuntime.async(function extraPromise$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: promise = new Promise(function (res, rej) { resolve = res; reject = rej; }); _context4.next = 3; return _regeneratorRuntime.awrap(delay(0)); case 3: return _context4.abrupt("return", { promise: promise, reject: reject, resolve: resolve }); case 4: case "end": return _context4.stop(); } } }); } /** * 按照 push 顺序执行并发的任务 * 防止并发多个任务只执行一个任务后其他任务被销毁 * * @typeParam R 自定义返回值类型 * * @returns push 将异步操作加入任务队列,run 按顺序执行任务队列里的所有异步操作 * * @example * * ```js * * const tasks = concurrentTask<MessageData[] | undefined>() * * for (let i = 0; i < messages.length; i++) { * tasks.push(() => {}) // tasks.push(Promise<any>) * } * const res = await tasks.run() * * ``` */ export function concurrentTask() { var i = 0; var tasks = []; var run = function run() { return _regeneratorRuntime.async(function run$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: return _context5.abrupt("return", Promise.all(tasks).then(function (arr) { return arr.sort(function (a, b) { return a.index - b.index; }).map(function (i) { return i.res; }); })); case 1: case "end": return _context5.stop(); } } }); }; var push = function push(task) { var order = i++; tasks.push(new Promise(function (resolve, reject) { task().then(function (res) { resolve({ index: order, res: res }); })["catch"](reject); })); }; return { push: push, run: run }; } var pendingTask = {}; /** * 执行异步任务, 它会处理重复发起的任务 * @param id 任务唯一索引 * @param task 异步执行方法 * * @example * * ```js * const res = await executeAsyncTask<User>('get-user', async () => Promise<User>) // 如多次发起请求,只会请求一次 * ``` */ export function executeAsyncTask(id, task) { var res, err, _iterator, _isArray, _i, _ref, t; return _regeneratorRuntime.async(function executeAsyncTask$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: if (!(id in pendingTask)) { _context6.next = 2; break; } return _context6.abrupt("return", new Promise(function (resolve, reject) { pendingTask[id].push({ resolve: resolve, reject: reject }); })); case 2: _context6.prev = 2; pendingTask[id] = []; _context6.next = 6; return _regeneratorRuntime.awrap(task()); case 6: res = _context6.sent; _context6.next = 12; break; case 9: _context6.prev = 9; _context6.t0 = _context6["catch"](2); _context6.t0 = _context6.t0; case 12: _iterator = pendingTask[id], _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator](); case 13: if (!_isArray) { _context6.next = 19; break; } if (!(_i >= _iterator.length)) { _context6.next = 16; break; } return _context6.abrupt("break", 27); case 16: _ref = _iterator[_i++]; _context6.next = 23; break; case 19: _i = _iterator.next(); if (!_i.done) { _context6.next = 22; break; } return _context6.abrupt("break", 27); case 22: _ref = _i.value; case 23: t = _ref; if (err != null) { t.reject(err); } else { t.resolve(res); } case 25: _context6.next = 13; break; case 27: delete pendingTask[id]; if (!(err != null)) { _context6.next = 30; break; } throw err; case 30: return _context6.abrupt("return", res); case 31: case "end": return _context6.stop(); } } }, null, null, [[2, 9]]); }