使用Promise时,如何在Javascript异常后重试? [英] How can you retry after an exception in Javascript when using promises?

查看:160
本文介绍了使用Promise时,如何在Javascript异常后重试?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Bluebird Promise库。我有一连串的承诺函数,如下所示:

I'm using the Bluebird promise library. I have a chain of promisified functions like the following:

    receiveMessageAsync(params)
    .then(function(data)) {
        return [data, handleMessageAsync(request)];
    })
    .spread(function(data, response) {
        return [response, deleteMessageAsync(request)];
    })
    .spread(function(response, data) {
        return sendResponseAsync(response);
    })
    .then(function(data) {
        return waitForMessage(data);
    })
    .catch (function(err) {
       // handle error here
    });

有时sendMessage会失败,因为例如无法响应的服务器。我希望代码能够一直尝试永远响应,直到成功为止。您不能简单地将sendMessage包装在catch中,因为它实际上并没有引发异常,我想,它调用了错误函数,在此应许代码中,该函数是底部的 catch。因此,必须在捕获部分中提供某种重试发送消息的方法。问题是,即使我在 catch中的循环中重试,我仍然无法跳到promise链并执行剩余的承诺功能。我该如何处理?

Occasionally sendMessage will fail because, let's say, the server to respond to isn't available. I want the code to keep on trying to respond forever until it succeeds. You can't simply wrap the sendMessage in a catch because it doesn't actually throw an exception, I suppose, it calls the "error" function which, in this promisified code is the "catch" at the bottom. So there must be some way to "retry" send message in the "catch" section. The problem is that even if I retry in a loop in the "catch" I still have no way to jump up to the promise chain and execute the remaining promisified functions. How do I deal with this?

编辑:

我对HTTP帖子的重试最终看起来像这样:

My retry for a HTTP post ended up looking like this:

function retry(func) {
    return func()
        .spread(function(httpResponse) {
            if (httpResponse.statusCode != 200) {
                Log.error("HTTP post returned error status: "+httpResponse.statusCode);
                Sleep.sleep(5);
                return retry(func);
            }
        })
        .catch(function(err) {
            Log.err("Unable to send response via HTTP");
            Sleep.sleep(5);
            return retry(func);
        });
}


推荐答案

下面是一个示例重试函数(尚未测试):

Here's a sample retry function (not yet tested):

function retry(maxRetries, fn) {
  return fn().catch(function(err) { 
    if (maxRetries <= 0) {
      throw err;
    }
    return retry(maxRetries - 1, fn); 
  });
}

这个想法是,您可以包装一个返回promise的函数,将捕获并重试错误,直到用尽重试。因此,如果您要重试 sendResponseAsync

The idea is that you can wrap a function that returns a promise with something that will catch and retry on error until running out of retries. So if you're going to retry sendResponseAsync:

receiveMessageAsync(params)
.then(function(data)) {
    return [data, handleMessageAsync(request)];
})
.spread(function(data, response) {
    return [response, deleteMessageAsync(request)];
})
.spread(function(response, data) {
    return retry(3, function () { return sendResponseAsync(response); });
})
.then(function(data) {
    return waitForMessage(data);
})
.catch (function(err) {
   // handle error here
});

因为 retry 承诺实际上不会抛出,直到所有重试用尽,您的呼叫链就可以继续。

Since the retry promise won't actually throw until all retries have been exhausted, your call chain can continue.

编辑

当然,如果愿意,也可以永远循环:

Of course, you could always loop forever if you preferred:

function retryForever(fn) {
  return fn().catch(function(err) { 
    return retryForever(fn); 
  });
}

这篇关于使用Promise时,如何在Javascript异常后重试?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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