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的子进程(child_process)调用系统命令的方法分享
Jun 05 NodeJs
NodeJS制作爬虫全过程(续)
Dec 22 NodeJs
Nodejs学习笔记之Global Objects全局对象
Jan 13 NodeJs
Windows系统中安装nodejs图文教程
Feb 28 NodeJs
Nodejs基于LRU算法实现的缓存处理操作示例
Mar 17 NodeJs
Ajax异步文件上传与NodeJS express服务端处理
Apr 01 NodeJs
用Nodejs搭建服务器访问html、css、JS等静态资源文件
Apr 28 NodeJs
NodeJS 实现手机短信验证模块阿里大于功能
Jun 19 NodeJs
详解使用PM2管理nodejs进程
Oct 24 NodeJs
Nodejs实现的操作MongoDB数据库功能完整示例
Feb 02 NodeJs
NodeJs入门教程之定时器和队列
Mar 08 NodeJs
nodejs实现日志读取、日志查找及日志刷新的方法分析
May 20 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
基于文本的访客签到簿
2006/10/09 PHP
关于Sphinx创建全文检索的索引介绍
2013/06/25 PHP
为PHP安装imagick时出现Cannot locate header file MagickWand.h错误的解决方法
2014/11/03 PHP
thinkphp普通查询与表达式查询实例分析
2014/11/24 PHP
imgAreaSelect 中文文档帮助说明
2011/10/08 Javascript
css transform 3D幻灯片特效实现步骤解读
2013/03/27 Javascript
jQuery实现自定义下拉列表
2015/01/05 Javascript
浅谈使用MVC模式进行JavaScript程序开发
2015/11/10 Javascript
js获取及修改网页背景色和字体色的方法
2015/12/29 Javascript
js与applet相互调用的方法
2016/06/22 Javascript
AngularJS 与百度地图的结合实例
2016/10/20 Javascript
js仿新浪微博消息发布功能
2017/02/17 Javascript
[js高手之路]设计模式系列课程-发布者,订阅者重构购物车的实例
2017/08/29 Javascript
Vue 按键修饰符处理事件的方法
2018/05/04 Javascript
Vue动态控制input的disabled属性的方法
2018/06/26 Javascript
Vue.js的复用组件开发流程完整记录
2018/11/29 Javascript
小试小程序云开发(小结)
2019/06/06 Javascript
Python实现基本线性数据结构
2016/08/22 Python
关于python3中setup.py小概念解析
2019/08/22 Python
在Matplotlib图中插入LaTex公式实例
2020/04/17 Python
Python中的wordcloud库安装问题及解决方法
2020/05/27 Python
使用Keras画神经网络准确性图教程
2020/06/15 Python
css3圆角样式分享自定义按钮样式
2013/12/27 HTML / CSS
时尚、社区、科技:SEVENSTORE
2019/04/26 全球购物
DOUGLAS波兰:在线销售香水和化妆品
2020/07/05 全球购物
灵泰克Java笔试题
2016/01/09 面试题
中学生寄语大全
2014/04/03 职场文书
进口业务员岗位职责
2014/04/06 职场文书
工地标语大全
2014/06/18 职场文书
社区服务活动小结
2014/07/08 职场文书
民警个人对照检查剖析材料
2014/09/17 职场文书
党的群众路线教育实践活动自我剖析材料
2014/10/08 职场文书
2015年校长新年寄语
2014/12/08 职场文书
2014年医院个人工作总结
2014/12/09 职场文书
2014预防青少年违法犯罪工作总结
2014/12/10 职场文书
承诺书应该怎么写?
2019/09/10 职场文书