/// /** * 微信小程序操作队列封装管理 * @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