@gdjiami/jslib
Version:
Jiami FrontEnd helpers and Services
353 lines (298 loc) • 8.07 kB
JavaScript
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]]);
}