博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nodejs异步请求重试策略总结
阅读量:5008 次
发布时间:2019-06-12

本文共 4264 字,大约阅读时间需要 14 分钟。

对于node开发同学经常要处理异步请求,然后根据请求的结果或请求成功后的状态码做不同的策略处理,众多策略中最常用的一种就是重试策略。针对重试策略我们往往还需要设定一定的规则,如重试次数、重试时间间隔、总体超时时间、重试判定等。针对以上问题,这里推荐一个工具包:bluebird-retry。

bluebird-retry基本用法如下:

var retry = require('bluebird-retry');function logFail() {    console.log(new Date().toISOString());    throw new Error('bail');}retry(logFail, { max_tries: 4, interval: 500 });

结果如下:

2014-05-29T23:16:28.941Z2014-05-29T23:16:29.445Z2014-05-29T23:16:29.946Z2014-05-29T23:16:30.447ZError: operation timed out

以上代码逻辑是,如果logFail函数报出异常或出错,则重试四次,每次间隔500毫秒。

bluebird-retry除了能够捕获异常外,还支持promise形式:

var Promise = require('bluebird');var retry = require('bluebird-retry'); var count = 0;function myfunc() {    console.log('myfunc called ' + (++count) + ' times');    if (count < 3) {        return Promise.reject(new Error('fail the first two times'));    } else {        return Promise.resolve('succeed the third time');    }}retry(myfunc).then(function(result) {    console.log(result);});

最终结果:

myfunc called 1 timesmyfunc called 2 timesmyfunc called 3 timessucceed the third time

他对promise的支持就为我们的异步请求处理打开了大门,我们可以将bluebirdrequestbluebird-retry三者结合起来,针对异步请求做重试策略:

var Promise = require('bluebird');var request = Promise.promisifyAll(require('request'));var retry = require('bluebird-retry');var config = require('../config/config');var log = require('../log');module.exports = function(options, method) {  options.timeout = options.timeout || config.requestTimeout;  var predicate = options.predicate || function(error) {    log.fatal('GET#' + method +'*retryError#-1#' + options.url + '#error:' + error.stack);    return error && error.toString() && error.toString().indexOf('ETIMEOUT') > -1;  };  delete options.predicate;  return retry(function(){    log.notice('GET#' + method +'*retry#' + options.url);    return request.getAsync(options);  }, {    max_tries: 3,    interval: 200,    backoff: 2,    predicate: predicate//对错误过滤处理,只有符合条件的错误才会做重试策略,比如超时  });}

以上代码就是只针对超时错误做重试处理。

如果你还有其他场景,比如对返回结果判断status,如果status不为0则重试,那么你只需要在适当时候抛出异常即可。可以参考如下实例:

function getToken(userId){    console.log("GET#getToken*start#userId:" + userId);    log.notice("GET#getToken*start#userId:" + userId);    return bluebirdRetry(function() {// 获取token,失败则重试三次        console.log("GET#getToken*retryStart#userId:" + userId);        log.notice("GET#getToken*retryStart#userId:" + userId);        return request.getAsync({           url: config.server.wxToken,           timeout: config.requestTimeout        }).then(function(response) {            var result = JSON.parse(response.body);            if (!result || result.returnValue !== 0) {// 如果status不为0则重试三次                console.log('GET#getToken*retryError#-1#url:' +                    config.server.wxToken + '#userId:' + user +                    '#error:' + (result && util.obj2ParamsString(result)));                log.fatal('GET#getToken*retryError#-1#url:' +                    config.server.wxToken + '#userId:' + user +                    '#error:' + (result && util.obj2ParamsString(result)));                throw new Error('getToken Error');            } else {                return result            }        });    }, {        max_tries: 3,        interval: 200,        backoff: 2    })    .then(function(result) {        console.log("GET#getToken*end#userId:" + userId + "#token:" + util.obj2ParamsString(result));        log.notice("GET#getToken*end#userId:" + userId + "#token:" + util.obj2ParamsString(result));        return result;    })    .catch(function(err) {        log.fatal("GET#getToken*error#userId:" + userId + "#token:" + config.server.wxToken + '#' + err);        log.fatal("GET#getToken*error#userId:" + userId + "#token:" + config.server.wxToken + '#' + err);        return {};    });}

然而有时候并不是所有的情况都想做重试,有些错误情况需要即可失败以便通知开发人员,这时候只要抛出throw new bluebirdRetry.StopError('GetWXImg Error!');即可,示例如下:

var retry = require('bluebird-retry');var i = 0;var err;var swing = function() {    i++;    console.log('strike ' + i);    if (i == 3) {        throw new retry.StopError('yer out');    }    throw new Error('still up at bat');}; retry(swing, {timeout: 10000}).caught(function(e) {    console.log(e.message)});

执行结果:

strike 1strike 2strike 3yer out

关于他的详细文档可以参考:

关于node中错误和异常的处理策略可以参考:

转载于:https://www.cnblogs.com/dojo-lzz/p/6580753.html

你可能感兴趣的文章
z-stack中数据的发送,广播、组播、点对点
查看>>
Practial Vim 学习笔记一
查看>>
.NET中使用js实现百度搜索下拉提示效果[不是局部刷新,呜呜。。]
查看>>
ITCAST视频-Spring学习笔记(使用Spring的注解方式实现AOP入门)
查看>>
关于二维码“QR”的6大注意事项
查看>>
MySQL - 常用命令及常用查询SQL
查看>>
C# .NET MVC 接收 JSON ,POST,WCF 无缝隙切换
查看>>
android获取USB设备的名称
查看>>
JavaPersistenceWithHibernate第二版笔记-第七章-005排序的集合(@org.hibernate.annotations.SortComparator)...
查看>>
ue4同c#通信时的中文乱码问题
查看>>
黄老师架构师课程笔记(二)
查看>>
mvc性能优化
查看>>
C++学习笔记25:makefile文件2
查看>>
Maven 3 入门 -- 核心概念
查看>>
勾选框图片代替,两张图片进行切换
查看>>
在Windows Mobile和Wince(Windows Embedded CE)下使用.NET Compact Framework进行GPS NMEA data数据分析的开发...
查看>>
thymeleaf-extras-db 0.0.1发布,select标签加载数据的新姿势
查看>>
多线程程序设计的8个规则
查看>>
file 读取方式
查看>>
五、面向对象的应用范围
查看>>