NodeJS承诺不重置

问题描述 投票:0回答:2

如果失败,我正在使用promises重试API请求。我这样使用它:

var promise = new Promise((resolve, reject) => {
    client.ApiRequest(params, function(data) {
        if (!Array.isArray(data)) {
            console.log("There was an error with the request.");
            reject("Rate Limit Exceeded");
            return;
        }
        ...
        resolve();
    });
});
Utils.retry(promise, 1500);

然后Utils.retry方法如下:

static delay(delayMS) {
    return new Promise(function(resolve, reject){
        setTimeout(resolve, delayMS);
    });
}

static retry(operation, delayMS) {
    return operation.catch((err) => {
        console.log(err);
        return Utils.delay(delayMS).then(function(){
            return Utils.retry(operation, delayMS)
        });
    });
}

正如你所看到的,它从承诺中捕获了reject()并使用delay()等待重试之前。代码运行,但似乎一旦承诺不断陷入拒绝状态,承诺就会失败。

例如,当它失败时,它会延迟,然后重试承诺只是为了输出相同的拒绝消息。但是,在第一个函数中,它不会在后续重试时打印出“请求有错误”消息,因此我认为它甚至不会重试。

有没有办法重置这个promise状态,以便在重试时它执行promise函数中的所有代码?

javascript node.js es6-promise
2个回答
1
投票

不要传递对原始承诺的引用。每次都会传递新的承诺。这是你如何做到这一点。

// a function that returns a new promise
var createPromise = function() {
    return new Promise((resolve, reject) => {
        client.ApiRequest(params, function(data) {
            if (!Array.isArray(data)) {
                console.log("There was an error with the request.");
                reject("Rate Limit Exceeded");
                return;
            }
            ...
            resolve();
        });
    });
}    

-

static delay(delayMS) {
    return new Promise(function(resolve, reject){
        setTimeout(resolve, delayMS);
    });
}

static retry(operation, delayMS) {
    return operation().catch((err) => { //invoke the promise function
        console.log(err);
        return Utils.delay(delayMS).then(function(){
            return Utils.retry(operation, delayMS)
        });
    });
}

Utils.retry(promise, 1500);

0
投票

它给你相同的结果,因为你传递相同的,已经被拒绝的,承诺回到你的重试处理程序。您需要创建一个新的承诺,以便返回重试处理程序以使其正常工作。

这意味着您可能需要修改重试处理程序以接受promise工厂(一个返回所需承诺的函数),而不是promise本身。所以你可以像这样修改你的代码:

// Make function to return this promise instead:
var makePromise = () => {
    return new Promise((resolve, reject) => {
        client.ApiRequest(params, function(data) {
            if (!Array.isArray(data)) {
                console.log("There was an error with the request.");
                reject("Rate Limit Exceeded");
                return;
            }
            ...
            resolve();
        });
    });
};

Utils.retry(makePromise, 1500);

-

static delay(delayMS) {
    return new Promise(function(resolve, reject){
        setTimeout(resolve, delayMS);
    });
}

static retry(operation, delayMS) {
    // Note the () after operation. This function now expects operation
    // to be a function that returns a promise.
    return operation().catch((err) => {
        console.log(err);
        return Utils.delay(delayMS).then(function(){
            return Utils.retry(operation, delayMS)
        });
    });
}
© www.soinside.com 2019 - 2024. All rights reserved.