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 相关文章推荐
基于 Docker 开发 NodeJS 应用
Jul 30 NodeJs
轻松创建nodejs服务器(9):实现非阻塞操作
Dec 18 NodeJs
NodeJS遍历文件生产文件列表功能示例
Jan 22 NodeJs
NodeJs使用Mysql模块实现事务处理实例
May 31 NodeJs
深入理解Nodejs Global 模块
Jun 03 NodeJs
详解nodeJS之二进制buffer对象
Jun 03 NodeJs
nodejs操作mongodb的增删改查功能实例
Nov 09 NodeJs
nodejs实现的简单web服务器功能示例
Mar 15 NodeJs
webstorm中配置nodejs环境及npm的实例
May 15 NodeJs
Nodejs核心模块之net和http的使用详解
Apr 02 NodeJs
Nodejs技巧之Exceljs表格操作用法示例
Nov 06 NodeJs
windows如何把已安装的nodejs高版本降级为低版本(图文教程)
Dec 14 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 反向排序和随机排序代码
2010/06/30 PHP
PHP MemCached高级缓存配置图文教程
2010/08/05 PHP
《PHP编程最快明白》第五讲:php目录、文件操作
2010/11/01 PHP
php中过滤非法字符的具体实现
2013/10/29 PHP
PHP调用C#开发的dll类库方法
2014/07/28 PHP
thinkPHP简单导入和使用阿里云OSSsdk的方法
2017/03/15 PHP
CL vs ForZe BO5 第五场 2.13
2021/03/10 DOTA
Javascript实现的分页函数
2006/12/22 Javascript
JavaScript具有类似Lambda表达式编程能力的代码(改进版)
2010/09/14 Javascript
JS常用字符串处理方法应用总结
2014/05/22 Javascript
jquery中attr和prop的区别分析
2015/03/16 Javascript
js 中获取制定的cook信息实现方法
2016/11/19 Javascript
vue指令以及dom操作详解
2017/03/04 Javascript
原生JS实现圣旨卷轴展开效果
2017/03/06 Javascript
jQuery获取table表中的td标签(实例讲解)
2017/07/28 jQuery
详解从零搭建 vue2 vue-router2 webpack3 工程
2017/11/22 Javascript
js防抖和节流的深入讲解
2018/12/06 Javascript
JavaScript仿京东秒杀倒计时
2020/03/17 Javascript
Python 读写文件和file对象的方法(推荐)
2016/09/12 Python
python机器学习理论与实战(一)K近邻法
2021/01/28 Python
python实现NB-IoT模块远程控制
2018/06/20 Python
OpenCV+python手势识别框架和实例讲解
2018/08/03 Python
Python 单元测试(unittest)的使用小结
2018/11/14 Python
Python多线程threading join和守护线程setDeamon原理详解
2020/03/18 Python
Pytest框架之fixture的详细使用教程
2020/04/07 Python
Python实现疫情通定时自动填写功能(附代码)
2020/05/27 Python
英国Boots旗下太阳镜网站:Boots Designer Sunglasses
2018/07/07 全球购物
美国女士内衣在线折扣商店:One Hanes Place
2019/03/24 全球购物
幼师自荐信
2013/10/26 职场文书
银行主办会计岗位职责
2014/08/13 职场文书
预备党员群众路线思想汇报2014
2014/10/25 职场文书
医院消毒隔离制度
2015/08/05 职场文书
2016党员干部政治学习心得体会
2016/01/23 职场文书
又涨知识了,自律到底多重要?
2019/06/27 职场文书
使用python向MongoDB插入时间字段的操作
2021/05/18 Python
spring IOC容器的Bean管理XML自动装配过程
2022/05/30 Java/Android