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 相关文章推荐
使用upstart把nodejs应用封装为系统服务实例
Jun 01 NodeJs
NodeJS学习笔记之网络编程
Aug 03 NodeJs
使用nodejs开发cli项目实例
Jun 03 NodeJs
nodeJs爬虫获取数据简单实现代码
Mar 29 NodeJs
nodejs密码加密中生成随机数的实例代码
Jul 17 NodeJs
NodeJs form-data格式传输文件的方法
Dec 13 NodeJs
nodeJS微信分享
Dec 20 NodeJs
NodeJS如何实现同步的方法示例
Aug 24 NodeJs
Nodejs Express 通过log4js写日志到Logstash(ELK)
Aug 30 NodeJs
Nodejs使用archiver-zip-encrypted库加密压缩文件时报错(解决方案)
Nov 18 NodeJs
浅谈vue websocket nodeJS 进行实时通信踩到的坑
Sep 22 NodeJs
浅谈Node的内存泄露问题
May 06 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文件操作的详解
2013/06/05 PHP
php中base_convert()进制数字转换函数实例
2014/11/20 PHP
php抽象类用法实例分析
2015/07/07 PHP
利用switch语句进行多选一判断的实例代码
2016/11/14 PHP
php使用ftp实现文件上传与下载功能
2017/07/21 PHP
thinkphp5.1框架模板赋值与变量输出示例
2020/05/25 PHP
安装PHP扩展时解压官方 tgz 文件后没有configure文件无法进行配置编译的问题
2020/08/26 PHP
基于jquery的direction图片渐变动画效果
2010/05/24 Javascript
JS this作用域以及GET传输值过长的问题解决方法
2013/08/06 Javascript
使用typeof方法判断undefined类型
2014/09/09 Javascript
javascript中字符串拼接详解
2014/09/26 Javascript
JavaScript检测上传文件大小的方法
2015/07/22 Javascript
javascript回调函数的概念理解与用法分析
2017/05/27 Javascript
详解基于Node.js的微信JS-SDK后端接口实现代码
2017/07/15 Javascript
浅谈JavaScript find 方法不支持IE的问题
2017/09/28 Javascript
seaJs使用心得之exports与module.exports的区别实例分析
2017/10/13 Javascript
快速搭建vue2.0+boostrap项目的方法
2018/04/09 Javascript
用ES6的class模仿Vue写一个双向绑定的示例代码
2018/04/20 Javascript
js正则相关知识点专题
2018/05/10 Javascript
vue data恢复初始化数据的实现方法
2019/10/31 Javascript
解决vue项目中遇到 Cannot find module ‘chalk‘ 报错的问题
2020/11/05 Javascript
[49:20]2014 DOTA2国际邀请赛中国区预选赛5.21 CIS VS TongFu
2014/05/22 DOTA
Python 元类使用说明
2009/12/18 Python
Windows安装Python、pip、easy_install的方法
2017/03/05 Python
Python使用asyncio包处理并发详解
2017/09/09 Python
numpy数组拼接简单示例
2017/12/15 Python
Django视图类型总结
2021/02/17 Python
《宋庆龄故居的樟树》教学反思
2014/04/07 职场文书
意外伤害赔偿协议书范本
2014/09/28 职场文书
大二学生自我检讨书
2014/10/23 职场文书
2014年创卫工作总结
2014/11/24 职场文书
小学六一儿童节活动总结
2015/05/05 职场文书
盗窃罪辩护词范文
2015/05/21 职场文书
端午节将至,用Python爬取粽子数据并可视化,看看网友喜欢哪种粽子吧!
2021/06/11 Python
详解SpringBoot异常处理流程及原理
2021/06/21 Java/Android
Ruby使用Mysql2连接操作MySQL
2022/04/19 Ruby