javascript - 使用 promises 时如何在 Javascript 中出现异常后重试?

标签 javascript node.js exception-handling promise bluebird

我正在使用 Bluebird promise 库。我有一系列 promise 的功能,如下所示:

    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 中,因为它实际上并没有抛出异常,我想,它调用了“error”函数,在这个 promisified 代码中,它是底部的“catch”。因此,必须有某种方法可以在“捕获”部分中“重试”发送消息。问题是,即使我在“catch”循环中重试,我仍然无法跳转到 promise 链并执行剩余的 promise 功能。我该如何处理?

编辑:

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

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

最佳答案

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

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

这个想法是,您可以包装一个返回 promise 的函数,该函数将捕获并重试错误,直到用完重试。因此,如果您要重试 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 promise 在所有重试都用完之前不会真正抛出,因此您的调用链可以继续。

编辑:

当然,如果你愿意,你可以一直循环下去:

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

关于javascript - 使用 promises 时如何在 Javascript 中出现异常后重试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30471131/

相关文章:

javascript - RxJS 是否有办法处理订阅者 Uncaught Error ?

c# - 如何将异常标记为已记录(并且只记录一次)?

node.js - 限制数组字段的查询结果

node.js - 如何在 Sequelize upsert 中获取插入或更新记录的 ID?

php - 在异常处理程序中抛出异常

error-handling - 有什么方法可以处理和返回领域驱动设计实体和聚合根中的错误(非异常和异常)?

javascript - 在 API 调用后重新加载 Angular 指令以重新绘制 morris.js 图表

javascript - 主干验证不起作用

javascript - 使用javascript获取div中的span元素

node.js - 优雅地处理 Node Js 中的异常