Javascript:使用setTimeout重试的函数 [英] Javascript: Function that retries with setTimeout

查看:148
本文介绍了Javascript:使用setTimeout重试的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个函数 downloadItem ,由于网络原因可能会失败,我希望能够在实际拒绝该项目之前重试几次。重试需要超时,因为如果出现网络问题,立即重试是没有意义的。

I have a function downloadItem that may fail for network reasons, I want to be able to retry it a few times before actually rejecting that item. The retries need to be with a timeout since if there is a network issue there is no point in retrying immediately.

这是我到目前为止所做的:

Here is what I have so far:

function downloadItemWithRetryAndTimeout(url, retry, failedReason) {
    return new Promise(function(resolve, reject) {
        try {
            if (retry < 0 && failedReason != null) reject(failedReason);

            downloadItem(url);
            resolve();
        } catch (e) {
            setTimeout(function() {
                downloadItemWithRetryAndTimeout(url, retry - 1, e);
            }, 1000);
        }
    });
}

显然这会因为我打电话的第二个(和开启时间)而失败 downloadItemWithRetryAndTimeout 我没有按要求返回承诺。

Obviously this will fail since the second (and on) time I call downloadItemWithRetryAndTimeout I don't return a promise as required.

如何让它与第二个承诺正常工作?

How do I make it work correctly with that second promise?

PS因为代码在NodeJS中运行很重要。

P.S. incase it matters the code is running in NodeJS.

推荐答案

我有两个想法:

移动迭代函数downloadItemWithRetryAndTimeout的promise - 现在resolve()将可用于所有迭代:

Move the promise out side of the iterated function downloadItemWithRetryAndTimeout - now resolve() will available to all iterations:

function downloadWrapper(url, retry) {
    return new Promise(function (resolve, reject) {
        function downloadItemWithRetryAndTimeout(url, retry, failedReason) {

            try {
                if (retry < 0 && failedReason != null)
                    reject(failedReason);

                downloadItem(url);
                resolve();
            } catch (e) {
                setTimeout(function () {
                    downloadItemWithRetryAndTimeout(url, retry - 1, e);
                }, 1000);
            }

        }

        downloadItemWithRetryAndTimeout(url, retry, null);
    });
}

此解决方案有效,但它违反了承诺链,这是一种反模式:
当每次迭代返回一个promise时,只需解析promise,然后使用.then解析之前的promise,依此类推:

This solution works, but it's an anti pattern as it breaks the promise chain: As each iteration returns a promise, just resolve the promise, and use .then to resolve the previous promise, and so on:

function downloadItemWithRetryAndTimeout(url, retry, failedReason) {
    return new Promise(function (resolve, reject) {
        try {
            if (retry < 0 && failedReason != null)
                reject(failedReason);

            downloadItem(url);
            resolve();
        } catch (e) {
            setTimeout(function () {
                downloadItemWithRetryAndTimeout(url, retry - 1, e).then(function () {
                    resolve();
                });
            }, 1000);
        }
    });
}

这篇关于Javascript:使用setTimeout重试的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆