我有一个包含在超时承诺中的服务器请求。
var pendingRequest = WinJS.Promise.timeout(5000, requestAsync)
。
用户还在UI上有一个“取消”按钮,通过执行pendingRequest.cancel()
主动取消请求。但是,没有办法发现用户已取消了承诺或超时(因为内部超时也会调用promise.cancel()
)。
WinJS.Promise.timeout本来是好的,它会在错误状态下使用不同的Error
对象(如“超时”而不是“已取消”)移动承诺。
知道如何确定请求是否已被超时取消?
更新:此解决方案如何:
(function (P) {
var oldTimeout = P.timeout
P.timeout = function (t, promise) {
var timeoutPromise = oldTimeout(t);
if (promise) {
return new WinJS.Promise(function (c, e, p) {
promise.then(c,e,p);
timeoutPromise.then(function () {
e(new WinJS.ErrorFromName("Timeout", "Timeout reached after " + t + "ms"));
});
});
} else {
return timeoutPromise;
}
};
})(WinJS.Promise);
答案 0 :(得分:1)
...承诺进入错误状态,其值为Error("已取消")
因此,可以在错误处理程序中检测到error.message === 'Canceled'
。
此外,WinJS.Promise
允许在施工时指定onCancel
回调。
var promise = new WinJS.Promise(init, onCancel);
其中init
和onCancel
都是函数。
修改强>
好的,对不起,我误解了这个问题。我现在明白你希望区分超时和手动取消的承诺。
是的,可以通过向两者提供适当的消息来完成:
onCancel
回拨首先,使用.timeout()方法扩展WinJS.Promise.prototype:
(function(P) {
P.prototype.timeout = function (t) {
var promise = this;
promise.message = 'Canceled';
P.timeout(t).then(function() {
promise.message = 'Timeout';
promise.cancel();
});
return promise.then(null, function() {
if(error.message == 'Canceled') {
throw new Error(promise.message); //This allows a chained "catch" to see "Canceled" or "Timeout" as its e.message.
} else {
throw error; //This allows a chained "catch" to see a naturally occurring message as its e.message.
}
});
};
})(WinJS.Promise);
这成为WinJS.Promise()的每个实例的方法,因此不会与静态方法WinJS.Promise.timeout()
冲突。
现在,使用.timeout()
方法,如下所示:
function init() {
//whatever ...
}
function onCancel() {
console.log('onCacnel handler: ' + this.message || `Canceled`);
}
var promise = new WinJS.Promise(init, onCancel);
promise.timeout(3000).then(null, function(error) {
console.log('chained catch handler: ' + error.message);
});
promise.cancel();
/*
* With `promise.cancel()` uncommented, `this.message` and `error.message` will be "Canceled".
* With `promise.cancel()` commented out, `this.message` and `error.message` will be "Timeout".
*/
Demo(带有按钮动画的额外代码)。