如何确定WinJS.Promise是否被超时或cancel()调用取消

时间:2015-04-14 23:34:45

标签: javascript promise winjs cancellation

我有一个包含在超时承诺中的服务器请求。

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);

1 个答案:

答案 0 :(得分:1)

根据the documentation

  

...承诺进入错误状态,其值为Error("已取消")

因此,可以在错误处理程序中检测到error.message === 'Canceled'

此外,WinJS.Promise允许在施工时指定onCancel回调。

var promise = new WinJS.Promise(init, onCancel);

其中initonCancel都是函数。

Here's a demo

修改

好的,对不起,我误解了这个问题。我现在明白你希望区分超时和手动取消的承诺。

是的,可以通过向两者提供适当的消息来完成:

  • WinJS承诺的onCancel回拨
  • 一个被束缚的" catch"回调。

首先,使用.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(带有按钮动画的额外代码)。