179 lines
5.9 KiB
JavaScript
179 lines
5.9 KiB
JavaScript
|
"use strict";
|
|||
|
/// <reference lib="es6"/>
|
|||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|||
|
/**
|
|||
|
* 微信小程序操作队列封装管理
|
|||
|
* @example var rq = new WxQueue(wx.requst);
|
|||
|
* @template TParam 微信操作参数类型
|
|||
|
* @template TTask 微信操返回task类型
|
|||
|
*/
|
|||
|
var WxQueue = /** @class */ (function () {
|
|||
|
/**
|
|||
|
* 创建Wx操作队列
|
|||
|
* @param wxFunc Wx操作函数
|
|||
|
* @param maxLength 最大队列长度,默认10
|
|||
|
*/
|
|||
|
function WxQueue(wxFunc, maxLength) {
|
|||
|
if (maxLength === void 0) { maxLength = 10; }
|
|||
|
/**
|
|||
|
* 任务ID计数器
|
|||
|
*/
|
|||
|
this.taskid = 0;
|
|||
|
/**
|
|||
|
* 待完成队列
|
|||
|
*/
|
|||
|
this.todo = [];
|
|||
|
/**
|
|||
|
* 保持正在运行的任务
|
|||
|
*/
|
|||
|
this.taskMap = new Map();
|
|||
|
this.operator = wxFunc;
|
|||
|
this.MAX = maxLength || 10;
|
|||
|
}
|
|||
|
/**
|
|||
|
* 向队列中添加操作
|
|||
|
* @param param 微信操作
|
|||
|
*/
|
|||
|
WxQueue.prototype.push = function (param) {
|
|||
|
var _this = this;
|
|||
|
var 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: function () { _this._abort(id); },
|
|||
|
onProgressUpdate: function (callback) { _this._onProgress(id, callback); },
|
|||
|
onHeadersReceived: function (callback) { _this._onHeaders(id, callback); }
|
|||
|
};
|
|||
|
};
|
|||
|
/**
|
|||
|
* check and do next task
|
|||
|
*/
|
|||
|
WxQueue.prototype._next = function () {
|
|||
|
if (this.todo.length > 0 && this.taskMap.size < this.MAX) {
|
|||
|
var _a = this.todo.shift(), taskid = _a[0], taskOptions = _a[1];
|
|||
|
this._process(taskid, taskOptions);
|
|||
|
}
|
|||
|
};
|
|||
|
/**
|
|||
|
* process a task
|
|||
|
* @param id task ID
|
|||
|
* @param options task param
|
|||
|
*/
|
|||
|
WxQueue.prototype._process = function (id, options) {
|
|||
|
var _this = this;
|
|||
|
var oldComplete = options.complete;
|
|||
|
var timeoutFailHandle;
|
|||
|
var taskTimeoutCancelled = false;
|
|||
|
var task;
|
|||
|
options.complete = function (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
|
|||
|
var oldFail_1 = options.fail;
|
|||
|
if (oldFail_1) {
|
|||
|
options.fail = function (res) {
|
|||
|
if (taskTimeoutCancelled) {
|
|||
|
res.errMsg = (res.errMsg || '').split(':', 1)[0] + ": timeout";
|
|||
|
res.timeout = true;
|
|||
|
}
|
|||
|
if (oldFail_1) {
|
|||
|
oldFail_1.call(options, res);
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
// 计时器 自定义超时
|
|||
|
timeoutFailHandle = setTimeout(function () {
|
|||
|
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
|
|||
|
*/
|
|||
|
WxQueue.prototype._abort = function (taskid) {
|
|||
|
var index = this.todo.findIndex(function (v) { return v[0] === taskid; });
|
|||
|
if (index >= 0) {
|
|||
|
var 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 回调操作
|
|||
|
*/
|
|||
|
WxQueue.prototype._onProgress = function (taskid, callback) {
|
|||
|
var result = this.todo.find(function (v) { return v[0] === taskid; });
|
|||
|
if (result) {
|
|||
|
result[1].onProgressUpdate = callback;
|
|||
|
}
|
|||
|
else if (this.taskMap.has(taskid)) {
|
|||
|
this.taskMap.get(taskid)[0].onProgressUpdate(callback);
|
|||
|
}
|
|||
|
};
|
|||
|
WxQueue.prototype._onHeaders = function (taskid, callback) {
|
|||
|
var result = this.todo.find(function (v) { return v[0] === taskid; });
|
|||
|
if (result) {
|
|||
|
result[1].onHeadersReceived = callback;
|
|||
|
}
|
|||
|
else if (this.taskMap.has(taskid)) {
|
|||
|
this.taskMap.get(taskid)[0].onHeadersReceived(callback);
|
|||
|
}
|
|||
|
};
|
|||
|
return WxQueue;
|
|||
|
}());
|
|||
|
exports.WxQueue = WxQueue;
|
|||
|
//# sourceMappingURL=index.js.map
|