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 相关文章推荐
nodejs 中模拟实现 emmiter 自定义事件
Feb 22 NodeJs
详解nodeJS之二进制buffer对象
Jun 03 NodeJs
nodejs mysql 实现分页的方法
Jun 06 NodeJs
NodeJs中express框架的send()方法简介
Jun 20 NodeJs
使用nodejs+express实现简单的文件上传功能
Dec 27 NodeJs
Nodejs连接mysql并实现增、删、改、查操作的方法详解
Jan 04 NodeJs
用Electron写个带界面的nodejs爬虫的实现方法
Jan 29 NodeJs
nodejs实现百度舆情接口应用示例
Feb 07 NodeJs
nodejs脚本centos开机启动实操方法
Mar 04 NodeJs
nodejs如何在package.json中设置多条启动命令
Mar 16 NodeJs
nodejs使用Sequelize框架操作数据库的实现
Oct 21 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
PHP If Else(elsefi) 语句
2013/04/07 PHP
跟我学Laravel之请求与输入
2014/10/15 PHP
windows下安装php的memcache模块的方法
2015/04/07 PHP
PHP文件缓存类实现代码
2015/10/26 PHP
php使用curl通过代理获取数据的实现方法
2016/05/16 PHP
Input 特殊事件onpopertychange和oninput
2009/06/17 Javascript
onkeydown事件解决按回车键直接提交数据的需求
2013/04/11 Javascript
javascript中new关键字详解
2015/12/14 Javascript
模拟javascript中的sort排序(简单实例)
2016/08/17 Javascript
使用Browserify来实现CommonJS的浏览器加载方法
2017/05/14 Javascript
JavaScript实现三级联动效果
2017/07/15 Javascript
深入Vue-Router路由嵌套理解
2018/08/13 Javascript
详解Node.js 中使用 ECDSA 签名遇到的坑
2018/11/26 Javascript
vue+element项目中过滤输入框特殊字符小结
2019/08/07 Javascript
vue 在单页面应用里使用二级套嵌路由
2020/12/19 Vue.js
[05:13]2018DOTA2亚洲邀请赛主赛事第二日战况回顾 LGD、VG双雄携手晋级
2018/04/05 DOTA
详解JavaScript编程中的window与window.screen对象
2015/10/26 Python
python实现域名系统(DNS)正向查询的方法
2016/04/19 Python
python 表达式和语句及for、while循环练习实例
2017/07/07 Python
对Python中列表和数组的赋值,浅拷贝和深拷贝的实例讲解
2018/06/28 Python
django自带serializers序列化返回指定字段的方法
2019/08/21 Python
python内置函数sorted()用法深入分析
2019/10/08 Python
python实现全排列代码(回溯、深度优先搜索)
2020/02/26 Python
Python sorted排序方法如何实现
2020/03/31 Python
Python命令行参数定义及需要注意的地方
2020/11/30 Python
意大利团购网站:Groupon意大利
2016/10/11 全球购物
新西兰廉价汽车租赁:Snap Rentals
2018/09/14 全球购物
如何理解委托
2012/01/06 面试题
物业管理公司实习生自我鉴定
2013/09/19 职场文书
毕业生个人求职信范例分享
2013/12/17 职场文书
茶叶店创业计划书范文
2014/01/19 职场文书
2014年双拥工作总结
2014/11/21 职场文书
2015年六一儿童节活动方案
2015/05/05 职场文书
一般纳税人申请报告
2015/05/18 职场文书
教你怎么用Python处理excel实现自动化办公
2021/04/30 Python
教你怎么用Python实现GIF动图的提取及合成
2021/06/15 Python