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的url截取模块url-extract的使用实例
Nov 18 NodeJs
利用NodeJS和PhantomJS抓取网站页面信息以及网站截图
Nov 18 NodeJs
Nodejs实现的一个简单udp广播服务器、客户端
Sep 25 NodeJs
轻松创建nodejs服务器(4):路由
Dec 18 NodeJs
轻松创建nodejs服务器(9):实现非阻塞操作
Dec 18 NodeJs
mac下的nodejs环境安装的步骤
May 24 NodeJs
nodejs中art-template模板语法的引入及冲突解决方案
Nov 07 NodeJs
nodejs基于WS模块实现WebSocket聊天功能的方法
Jan 12 NodeJs
Nodejs模块的调用操作实例分析
Dec 25 NodeJs
详解nodejs 配置文件处理方案
Jan 02 NodeJs
NodeJs 实现简单WebSocket即时通讯的示例代码
Aug 05 NodeJs
Nodejs + Websocket 指定发送及群聊的实现
Jan 09 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中字符串和正则表达式详解
2014/10/23 PHP
php在数组中查找指定值的方法
2015/03/17 PHP
javascript 获取url参数和script标签中获取url参数函数代码
2010/01/22 Javascript
读jQuery之一(对象的组成)
2011/06/11 Javascript
jQuery获取Select选择的Text和Value(详细汇总)
2013/01/25 Javascript
js中function()使用方法
2013/12/24 Javascript
js输出阴历、阳历、年份、月份、周示例代码
2014/01/29 Javascript
jquery实现省市select下拉框的替换(示例代码)
2014/02/22 Javascript
javascript操纵OGNL标签示例代码
2014/06/16 Javascript
javascript中关于&& 和 || 表达式的小技巧分享
2015/04/10 Javascript
AngularJS 使用 UI Router 实现表单向导
2016/01/29 Javascript
在JavaScript中使用JSON数据
2016/02/15 Javascript
jquery实现右侧栏菜单选择操作
2016/03/04 Javascript
一波JavaScript日期判断脚本分享
2016/03/06 Javascript
JS模态窗口返回值兼容问题的完美解决方法
2016/05/28 Javascript
原生js仿jquery animate动画效果
2016/07/13 Javascript
jQuery与JS加载事件用法分析
2016/09/04 Javascript
javascript中的event loop事件循环详解
2018/12/14 Javascript
微信小程序使用蓝牙小插件
2019/09/23 Javascript
[01:36]极致酷炫!TI9典藏宝瓶+撼地者至宝展示
2019/06/11 DOTA
Python中数字以及算数运算符的相关使用
2015/10/12 Python
Python3的urllib.parse常用函数小结(urlencode,quote,quote_plus,unquote,unquote_plus等)
2016/09/18 Python
Python中XlsxWriter模块简介与用法分析
2018/04/24 Python
Python利用递归实现文件的复制方法
2018/10/27 Python
python怎么对数字进行过滤
2020/07/05 Python
美国背景检查、公共记录和人物搜索网站:BeenVerified
2018/02/25 全球购物
急诊科护士自我鉴定
2013/10/14 职场文书
优秀毕业生求职推荐信范文
2013/11/21 职场文书
运动会通讯稿150字
2014/02/15 职场文书
亲子运动会的活动方案
2014/08/17 职场文书
助学贷款贫困证明
2014/09/23 职场文书
机关作风建设剖析材料
2014/10/11 职场文书
酒店保洁员岗位职责
2015/02/26 职场文书
2015年物资管理工作总结
2015/05/20 职场文书
导游词之杭州西湖
2019/09/19 职场文书
公文写作:工伤事故分析报告怎么写?
2019/11/05 职场文书