xunfeiAI/node_modules/miniprogram-queue/es/index.js

172 lines
5.4 KiB
JavaScript
Raw Normal View History

2023-09-12 20:19:08 +08:00
/// <reference lib="es6"/>
/**
* 微信小程序操作队列封装管理
* @example var rq = new WxQueue(wx.requst);
* @template TParam 微信操作参数类型
* @template TTask 微信操返回task类型
*/
export class WxQueue {
/**
* 创建Wx操作队列
* @param wxFunc Wx操作函数
* @param maxLength 最大队列长度默认10
*/
constructor(wxFunc, maxLength = 10) {
/**
* 任务ID计数器
*/
this.taskid = 0;
/**
* 待完成队列
*/
this.todo = [];
/**
* 保持正在运行的任务
*/
this.taskMap = new Map();
this.operator = wxFunc;
this.MAX = maxLength || 10;
}
/**
* 向队列中添加操作
* @param param 微信操作
*/
push(param) {
const id = ++this.taskid;
if (this.taskMap.size < this.MAX) {
// task队列未满
return this._process(id, param);
}
else if (param.jump) {
// 插队
this.todo.unshift([id, param]);
}
else {
this.todo.push([id, param]);
}
return {
abort: () => { this._abort(id); },
onProgressUpdate: (callback) => { this._onProgress(id, callback); },
onHeadersReceived: (callback) => { this._onHeaders(id, callback); }
};
}
/**
* check and do next task
*/
_next() {
if (this.todo.length > 0 && this.taskMap.size < this.MAX) {
const [taskid, taskOptions] = this.todo.shift();
this._process(taskid, taskOptions);
}
}
/**
* process a task
* @param id task ID
* @param options task param
*/
_process(id, options) {
const oldComplete = options.complete;
let timeoutFailHandle;
let taskTimeoutCancelled = false;
let task;
options.complete = (res) => {
if (timeoutFailHandle) {
// 清理计时器
clearTimeout(timeoutFailHandle);
}
if (options.timestamp && this.taskMap.has(id)) {
res.time = this.taskMap.get(id)[1] || {};
res.time.response = Date.now();
}
this.taskMap.delete(id);
// 原始结束回调
if (oldComplete) {
if (taskTimeoutCancelled) {
res.errMsg = `${(res.errMsg || '').split(':', 1)[0]}: timeout`;
res.timeout = true;
}
oldComplete.call(options, res);
}
this._next();
};
if (options.timeout > 0) {
// 自定义timeout 拦截fail 注入timeout
const oldFail = options.fail;
if (oldFail) {
options.fail = (res) => {
if (taskTimeoutCancelled) {
res.errMsg = `${(res.errMsg || '').split(':', 1)[0]}: timeout`;
res.timeout = true;
}
if (oldFail) {
oldFail.call(options, res);
}
};
}
// 计时器 自定义超时
timeoutFailHandle = setTimeout(() => {
timeoutFailHandle = undefined;
taskTimeoutCancelled = true;
task.abort();
}, options.timeout);
}
task = this.operator(options);
// task progress polyfill
if (options.onProgressUpdate && task.onProgressUpdate) {
task.onProgressUpdate(options.onProgressUpdate);
}
// task onHeadersReceived
if (options.onHeadersReceived) {
task.onHeadersReceived(options.onHeadersReceived);
}
this.taskMap.set(id, [
task,
options.timestamp ? { send: Date.now() } : undefined
]);
return task;
}
/**
* stop and remove a task
* @param taskid - the id of task to abort
*/
_abort(taskid) {
const index = this.todo.findIndex(v => v[0] === taskid);
if (index >= 0) {
const completeCallback = this.todo[index][1].complete;
this.todo.splice(index, 1);
// call back complete.
if (completeCallback) {
completeCallback({ errMsg: 'request:fail abort', cancel: true, source: WxQueue.name });
}
}
else if (this.taskMap.has(taskid)) {
this.taskMap.get(taskid)[0].abort();
this.taskMap.delete(taskid);
}
}
/**
* progress update callback
* https://developers.weixin.qq.com/miniprogram/dev/api/network/download/DownloadTask.onProgressUpdate.html
* @param taskid - task id
* @param callback 回调操作
*/
_onProgress(taskid, callback) {
const result = this.todo.find(v => v[0] === taskid);
if (result) {
result[1].onProgressUpdate = callback;
}
else if (this.taskMap.has(taskid)) {
this.taskMap.get(taskid)[0].onProgressUpdate(callback);
}
}
_onHeaders(taskid, callback) {
const result = this.todo.find(v => v[0] === taskid);
if (result) {
result[1].onHeadersReceived = callback;
}
else if (this.taskMap.has(taskid)) {
this.taskMap.get(taskid)[0].onHeadersReceived(callback);
}
}
}
//# sourceMappingURL=index.js.map