我有一个包含在超时 promise 中的服务器请求。
var pendingRequest = WinJS.Promise.timeout(5000, requestAsync)
。
用户在 UI 上还有一个“取消”按钮,可以通过执行 pendingRequest.cancel()
主动取消请求。但是,无法发现 promise 已被用户或超时取消(因为超时也在内部调用 promise.cancel()
)。
如果 WinJS 更好。Promise.timeout 会使用不同的 Error
对象(例如“Timeout”而不是“Canceled”)将 promise 移动到错误状态。
知道如何确定请求是否因超时而被取消吗?
更新:这个解决方案怎么样:
(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);
最佳答案
根据 the documentation ,
... the promise enters the error state with a value of Error("Canceled")
因此,可以在您的错误处理程序中检测到 error.message === 'Canceled'
。
此外,WinJS.Promise
允许在构建时指定一个 onCancel
回调。
var promise = new WinJS.Promise(init, onCancel);
其中 init
和 onCancel
都是函数。
编辑
啊好的,抱歉我看错了问题。我现在了解到您希望区分超时和手动取消的 promise 。
是的,这可以通过向双方提供适当的消息来完成:
- WinJS promise 的
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 (带有按钮动画的额外代码)。
关于javascript - 如何确定 WinJS.Promise 是否被超时或 cancel() 调用取消,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29639152/