【问题标题】:Calling a function repeatedly until its promise is resolved or until a set timeout has passed重复调用一个函数,直到它的承诺被解决或直到设置的超时时间已经过去
【发布时间】:2015-11-17 08:29:22
【问题描述】:

我有一个函数会导致很多错误,所以我必须多次调用它才能最终给出正确的结果。它返回一个承诺,所以我围绕它创建了一个包装器,在拒绝时递归地调用它。

我想返回通过Bluebird 创建的new Promise,但在设置超时后必须拒绝。而且它必须不断地重复调用上面的函数。但在每次重复之前,我想检查它是否由于超时而被自动拒绝。

Bluebird 有一个 isRejected() 方法,但我似乎无法在承诺正文中使用它:

var promise = new Promise(function(resolve, reject){
    var self = this;
    setTimeout(reject, TIMEOUT*1000);
    return doSomethingWrapper();
    function doSomethingWrapper(){

        if(promise.isRejected()) return;
        // Error: Cannot read property 'isRejected' of undefined

        if(self.isRejected()) return;
        // Error: self.isRejected is not a function

        return doSomething().then(resolve, doSomethingWrapper).catch(doSomethingWrapper);
    }
});

还有其他解决方案吗?

【问题讨论】:

  • 在 promise 主体中使用它是没有意义的,因为doSomethingWrapper 被立即调用,所以setTimeout 回调不可能被触发,所以没有必要检查无论如何。

标签: javascript node.js promise bluebird


【解决方案1】:

创建超时承诺:

var timeout = Bluebird.delay(TIMEOUT * 1000).then(function () {
    return Bluebird.reject(new Error("Timed out"));
});

创建操作承诺:

var something = (function doSomethingWrapper() {
    if (timeout.isRejected()) {
        return;
    }

    return doSomething().catch(doSomethingWrapper);
})();

与他们比赛:

var promise = Bluebird.race(something, timeout);

【讨论】:

    【解决方案2】:

    这实际上可以以更简单的方式完成:

    Promise.try(function doSomethingWrapper(){ 
       return doSomething().catch(doSomethingWrapper); // retry
    }).timeout(TIMEOUT * 1000);
    

    不需要比赛:)

    【讨论】:

    • timeout 会取消递归吗?我没有发布这个答案,因为我不确定。
    猜你喜欢
    • 2017-02-24
    • 2019-08-21
    • 2021-08-19
    • 2021-05-19
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 2020-07-13
    • 2018-03-18
    相关资源
    最近更新 更多