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中自定义事件实例
Jun 20 NodeJs
NodeJS学习笔记之Http模块
Jan 13 NodeJs
NodeJS的Promise的用法解析
May 05 NodeJs
详解nodejs 文本操作模块-fs模块(二)
Dec 22 NodeJs
NodeJS配置HTTPS服务实例分享
Feb 19 NodeJs
nodejs使用express创建一个简单web应用
Mar 31 NodeJs
nodejs入门教程二:创建一个简单应用示例
Apr 24 NodeJs
基于nodejs 的多页面爬虫实例代码
May 31 NodeJs
Nodejs实现爬虫抓取数据实例解析
Jul 05 NodeJs
Nodejs对postgresql基本操作的封装方法
Feb 20 NodeJs
nodejs nedb 封装库与使用方法示例
Feb 06 NodeJs
Nodejs在局域网配置https访问的实现方法
Oct 17 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获取当前url路径的函数以及服务器变量
2013/06/29 PHP
解析PHP强制转换类型及远程管理插件的安全隐患
2014/06/30 PHP
PHP扩展程序实现守护进程
2015/04/16 PHP
PHP利用Cookie设置用户30分钟未操作自动退出功能
2017/07/03 PHP
php实现单笔转账到支付宝功能
2018/10/09 PHP
Javascript 事件流和事件绑定
2009/07/16 Javascript
onclick与listeners的执行先后问题详细解剖
2013/01/07 Javascript
将字符串转换成gb2312或者utf-8编码的参数(js版)
2013/04/10 Javascript
禁止选中文字兼容IE、Chrome、FF等
2013/09/04 Javascript
Jquery实现自定义窗口随意的拖拽
2014/03/12 Javascript
淘宝网提供的国内NPM镜像简介和使用方法
2014/04/17 Javascript
JavaScript sub方法入门实例(把字符串显示为下标)
2014/10/17 Javascript
基于jQuery实现的扇形定时器附源码下载
2015/10/20 Javascript
javascript匀速运动实现方法分析
2016/01/08 Javascript
jQuery实现字体颜色渐变效果的方法
2017/03/29 jQuery
JavaScript实现的反序列化json字符串操作示例
2018/07/18 Javascript
详解小程序开发经验:多页面数据同步
2019/05/18 Javascript
[02:04]2018DOTA2亚洲邀请赛Secret赛前采访
2018/04/03 DOTA
跟老齐学Python之Import 模块
2014/10/13 Python
基于wxpython实现的windows GUI程序实例
2015/05/30 Python
解决新django中的path不能使用正则表达式的问题
2018/12/18 Python
python实时获取外部程序输出结果的方法
2019/01/12 Python
Numpy 理解ndarray对象的示例代码
2020/04/03 Python
Django基于客户端下载文件实现方法
2020/04/21 Python
Python如何把字典写入到CSV文件的方法示例
2020/08/23 Python
Python字典实现伪切片功能
2020/10/28 Python
python+selenium自动化实战携带cookies模拟登陆微博
2021/01/19 Python
Opencv 图片的OCR识别的实战示例
2021/03/02 Python
马来西亚在线时尚女装商店:KEI MAG
2017/09/28 全球购物
《神奇的克隆》教学反思
2014/04/10 职场文书
俞敏洪一分钟演讲稿
2014/08/26 职场文书
2014幼儿园中班工作总结
2014/11/10 职场文书
离婚承诺书格式范文
2015/05/04 职场文书
队列队形口号
2015/12/25 职场文书
同学联谊会邀请函
2019/06/24 职场文书
SqlServer 垂直分表(减少程序改动)
2021/04/16 SQL Server