Nodejs回调加超时限制两种实现方法


Posted in NodeJs onJune 09, 2017

Nodejs回调加超时限制两种实现方法

Nodejs下的IO操作都是异步的,有时候异步请求返回太慢,不想无限等待回调怎么办呢?我们可以给回调函数加一个超时限制,到一定时间还没有回调就表示失败,继续后面的步骤。

方案1:用async的parallel实现

在这里我用到了async的parallel方法,parallel可以让若干个异步回调的方法并行执行,正常情况下,所有回调函数都完成后会汇集到parallel最终的回调函数里,但是有一种例外,如果其中一个步骤有错误抛出并直接调用parallel最终的回调函数,利用这个特点就可以实现我们要的功能。

我封装了一个函数asyncWrapper, 逻辑比较简单,直接看代码:

async-timer.js

const async = require('async');

const asyncWrapper = (fn, interval, ...args) =>{
  let final_callback = args[args.length-1];
  async.parallel([
    function(callback){
      args[args.length - 1] = callback;
      fn.apply(this, args);
    },
    function(callback){
      setTimeout(function(){
        callback(408);
      }, interval);
    }
  ],
  function(err, results){
    if(err==408 && results[0])err = null;
    final_callback.apply(this,[err].concat([results[0]]));
  });
}

if(module.parent){
  exports.asyncWrapper = asyncWrapper;
}else{
  let myfn = (arg_1, arg_2, callback) => {
    setTimeout(function(){
      callback(null,'value 1: '+arg_1,'value 2: '+arg_2);
    }, 1000);
  }
  asyncWrapper(myfn, 2000, 10, 20, (err, values)=>{
    console.log(`${err}, ${values}`);
  });
}

你可以直接运行这个js看看效果:

node async-timer.js

模块调用方法:

const asyncWrapper = require('./async-timer.js').asyncWrapper


const fn = (arg1, arg2, callback) => {
   //...假设这里过程很漫长,有可能超时
   callback(null, result_1, result_2);
}

asyncWrapper(
   fn,//异步函数
   10000,//超时时间
   'arg1_value',//异步函数的参数1
   'arg2_value',//异步函数的参数2,有多个参数就在后面继续加
   (err, results)=>{
    //results : [result_1, result_2]
    //最后的回调,results比较特殊,fn有多个返回值时,results会以数组的形式返回给你
   }
);

这种方案的好处是对node没有最低版本要求,引入async库就可以用,缺陷是最终返回的值都是在一个参数里面以数组的形式呈现。

方案2:用Promise实现

在promise里面加settimeout,超过时间就reject。

promise-timer.js

const promiseWrapper = (fn, interval, ...args) =>{
 let final_callback = args[args.length-1];
 new Promise((resolve, reject)=>{
 args[args.length - 1] = (err, ...vals)=>{
  if(err)reject(err);
  else resolve(vals);
 };
    fn.apply(this, args);
    setTimeout(_=>{
     reject('Promise time out');
    }, interval);
 })
 .then(
 result => {
  final_callback.apply(this, [null].concat(result));
 }
 )
  .catch(err=>{
   final_callback(err);
  })
}


if(module.parent){
  exports.promiseWrapper = promiseWrapper;
}else{
  let myfn = (arg_1, arg_2, callback) => {
    setTimeout(function(){
      callback(null,'value 1: '+arg_1,'value 2: '+arg_2);
    }, 1000);
  }
  promiseWrapper(myfn, 1000, 10, 20, (err, value_1, value_2)=>{
    console.log(`${err}, value 1: ${value_1} ... value 2: ${value_2}`);
  });
}

模块调用方法:

const asyncWrapper = require('./promise-timer.js').promiseWrapper


const fn = (arg1, arg2, callback) => {
   //...假设这里过程很漫长,有可能超时
   callback(null, result_1, result_2);
}

promiseWrapper(
   fn,//异步函数
   10000,//超时时间
   'arg1_value',//异步函数的参数1
   'arg2_value',//异步函数的参数2,有多个参数就在后面继续加
   (err, result_1, result_2)=>{
    //最后的回调
   }
);

这种方案要求nodejs版本高于5.0,支持Promise。

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

NodeJs 相关文章推荐
使用upstart把nodejs应用封装为系统服务实例
Jun 01 NodeJs
nodejs实现HTTPS发起POST请求
Apr 23 NodeJs
Nodejs学习item【入门手上】
May 05 NodeJs
nodejs入门教程五:连接数据库的方法分析
Apr 24 NodeJs
深入理解Nodejs Global 模块
Jun 03 NodeJs
详解NODEJS的http实现
Jan 04 NodeJs
Nodejs Express 通过log4js写日志到Logstash(ELK)
Aug 30 NodeJs
Nodejs让异步变成同步的方法
Mar 02 NodeJs
nodejs搭建本地服务器并访问文件操作示例
May 11 NodeJs
nodejs实现用户登录路由功能
May 22 NodeJs
纯异步nodejs文件夹(目录)复制功能
Sep 03 NodeJs
在nodejs中创建child process的方法
Jan 26 NodeJs
nodeJS实现路由功能实例代码
Jun 08 #NodeJs
nodeJS实现简单网页爬虫功能的实例(分享)
Jun 08 #NodeJs
详解nodejs异步I/O和事件循环
Jun 07 #NodeJs
浅析 NodeJs 的几种文件路径
Jun 07 #NodeJs
nodejs mysql 实现分页的方法
Jun 06 #NodeJs
nodejs利用ajax实现网页无刷新上传图片实例代码
Jun 06 #NodeJs
ajax +NodeJS 实现图片上传实例
Jun 06 #NodeJs
You might like
解决MySQL中文输出变成问号的问题
2008/06/05 PHP
PHP array操作10个小技巧分享
2011/06/23 PHP
浅谈PHP与C#的值类型指向区别的详解
2013/05/21 PHP
关于PHP转换超过2038年日期出错的问题解决
2017/06/28 PHP
PHP实现找出链表中环的入口节点
2018/01/16 PHP
高性能WEB开发 flush让页面分块,逐步呈现 flush让页面分块,逐步呈现
2010/06/19 Javascript
JQuery1.6 使用方法三
2011/11/23 Javascript
JS构建页面的DOM节点结构的实现代码
2011/12/09 Javascript
JS左右无缝滚动(一般方法+面向对象方法)
2012/08/17 Javascript
JavaScript用select实现日期控件
2015/07/17 Javascript
javascript每日必学之继承
2016/02/23 Javascript
JavaScript中的splice方法用法详解
2016/07/20 Javascript
在js中实现邮箱格式的验证方法(推荐)
2016/10/24 Javascript
javaScript产生随机数的用法小结
2018/04/21 Javascript
浅谈Webpack 是如何加载模块的
2018/05/24 Javascript
vue elementui form表单验证的实现
2018/11/11 Javascript
Vue实现菜单切换功能
2020/11/08 Javascript
深入浅析Python字符编码
2015/11/12 Python
python音频处理用到的操作的示例代码
2017/10/27 Python
python中logging包的使用总结
2018/02/28 Python
python中字符串的操作方法大全
2018/06/03 Python
对numpy数据写入文件的方法讲解
2018/07/09 Python
Django安装配置mysql的方法步骤
2018/10/15 Python
Python实现制度转换(货币,温度,长度)
2019/07/14 Python
django echarts饼图数据动态加载的实例
2019/08/12 Python
浅谈django 重载str 方法
2020/05/19 Python
opencv 阈值分割的具体使用
2020/07/08 Python
Linux面试题LINUX系统类
2015/11/25 面试题
毕业生精彩的自我评价分享
2013/10/06 职场文书
初一地理教学反思
2014/01/16 职场文书
上课迟到检讨书
2014/01/19 职场文书
优秀班干部事迹材料
2014/01/26 职场文书
鸿星尔克广告词
2014/03/21 职场文书
离职保密承诺书
2014/05/28 职场文书
党员志愿者活动方案
2014/08/28 职场文书
求职自荐信范文(优秀篇)
2015/03/27 职场文书