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中使用monk访问mongodb
Jul 06 NodeJs
Google官方支持的NodeJS访问API,提供后台登录授权
Jul 29 NodeJs
Windows 系统下设置Nodejs NPM全局路径
Apr 26 NodeJs
NodeJS和BootStrap分页效果的实现代码
Nov 07 NodeJs
Highcharts+NodeJS搭建数据可视化平台示例
Jan 01 NodeJs
nodejs实例解析(输出hello world)
Jan 03 NodeJs
nodejs基础知识
Feb 03 NodeJs
NodeJS处理Express中异步错误
Mar 26 NodeJs
Nodejs连接mysql并实现增、删、改、查操作的方法详解
Jan 04 NodeJs
nodejs实现日志读取、日志查找及日志刷新的方法分析
May 20 NodeJs
Nodejs libuv运行原理详解
Aug 21 NodeJs
nodeJs项目在阿里云的简单部署
Nov 27 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
Zend studio for eclipse中使php可以调用mysql相关函数的设置方法
2008/10/13 PHP
PHP substr()函数参数解释及用法讲解
2017/11/23 PHP
php apache开启跨域模式过程详解
2019/07/08 PHP
JavaScript 5 新增 Array 方法实现介绍
2012/02/06 Javascript
Javascript图像处理—亮度对比度应用案例
2013/01/03 Javascript
js判断undefined类型示例代码
2014/02/10 Javascript
JS判断网页广告是否被浏览器拦截过滤的代码
2015/04/05 Javascript
JavaScript实现信用卡校验方法
2015/04/07 Javascript
Vuejs第七篇之Vuejs过渡动画案例全面解析
2016/09/05 Javascript
最细致的vue.js基础语法 值得收藏!
2016/11/03 Javascript
jQuery复合事件用法示例
2017/06/10 jQuery
JS无限级导航菜单实现方法
2019/01/05 Javascript
微信小程序实现图片压缩
2019/12/03 Javascript
vue倒计时刷新页面不会从头开始的解决方法
2020/03/03 Javascript
JavaScript onclick事件使用方法详解
2020/05/15 Javascript
Angular5整合富文本编辑器TinyMCE的方法(汉化+上传)
2020/05/26 Javascript
vue data对象重新赋值无效(未更改)的解决方式
2020/07/24 Javascript
Javascript生成器(Generator)的介绍与使用
2021/01/31 Javascript
[02:36]DOTA2上海特锦赛 回忆电竞生涯的重要瞬间
2016/03/25 DOTA
[02:44]完美大师赛主赛事淘汰赛第二日观众采访
2017/11/24 DOTA
python中的reduce内建函数使用方法指南
2014/08/31 Python
Python实现识别手写数字大纲
2018/01/29 Python
python实现手机销售管理系统
2019/03/19 Python
python Django中models进行模糊查询的示例
2019/07/18 Python
python实现超市商品销售管理系统
2019/11/22 Python
如何在python开发工具PyCharm中搭建QtPy环境(教程详解)
2020/02/04 Python
python+excel接口自动化获取token并作为请求参数进行传参操作
2020/11/10 Python
Pycharm在指定目录下生成文件和删除文件的实现
2020/12/28 Python
使用html2canvas.js实现页面截图并显示或上传的示例代码
2018/12/18 HTML / CSS
收费员岗位职责
2015/02/14 职场文书
后天观后感
2015/06/08 职场文书
Mysql中存储引擎的区别及比较
2021/06/04 MySQL
MySQL 1130异常,无法远程登录解决方案详解
2021/08/23 MySQL
Python语言中的数据类型-序列
2022/02/24 Python
php解析非标准json、非规范json的方式实例
2022/05/10 PHP
全网非常详细的pytest配置文件
2022/07/15 Python