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框架Express的模板视图机制分析
Jul 19 NodeJs
nodejs简单实现中英文翻译
May 04 NodeJs
Nodejs抓取html页面内容(推荐)
Aug 11 NodeJs
浅谈Nodejs应用主文件index.js
Aug 28 NodeJs
nodejs个人博客开发第四步 数据模型
Apr 12 NodeJs
nodejs入门教程三:调用内部和外部方法示例
Apr 24 NodeJs
nodejs利用ajax实现网页无刷新上传图片实例代码
Jun 06 NodeJs
nodejs密码加密中生成随机数的实例代码
Jul 17 NodeJs
详解nodejs中express搭建权限管理系统
Sep 15 NodeJs
详解使用PM2管理nodejs进程
Oct 24 NodeJs
通过nodejs 服务器读取HTML文件渲染到页面的方法
May 17 NodeJs
如何利用nodejs自动定时发送邮件提醒(超实用)
Dec 01 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检测iis环境是否支持htaccess的方法
2014/02/18 PHP
Zend Framework动作助手Redirector用法实例详解
2016/03/05 PHP
提交表单后 PHP获取提交内容的实现方法
2016/05/25 PHP
php-fpm服务启动脚本的方法
2018/04/27 PHP
jQuery Study Notes学习笔记 (二)
2010/08/04 Javascript
javascript 45种缓动效果 非常酷
2011/06/28 Javascript
JS Date函数整理方便使用
2013/10/23 Javascript
zeroclipboard 单个复制按钮和多个复制按钮的实现方法
2014/06/14 Javascript
Jquery动态替换div内容及动态展示的方法
2015/01/23 Javascript
使用EVAL处理jqchart jquery 折线图返回数据无效的解决办法
2015/11/26 Javascript
浅析JS原型继承与类的继承
2016/04/07 Javascript
关于使用axios的一些心得技巧分享
2017/07/02 Javascript
Vue.js 2.5新特性介绍(推荐)
2017/10/24 Javascript
Vue实现表格批量审核功能实例代码
2019/05/28 Javascript
微信小程序 WXML节点信息查询详解
2019/07/29 Javascript
Python文件读取的3种方法及路径转义
2015/06/21 Python
Python验证码识别的方法
2015/07/10 Python
Ubuntu 16.04 LTS中源码安装Python 3.6.0的方法教程
2016/12/27 Python
简单了解Python3 bytes和str类型的区别和联系
2019/12/19 Python
python 实现分组求和与分组累加求和代码
2020/05/18 Python
美国专注于健康商品的网站:eVitamins
2017/01/23 全球购物
西班牙拥有最佳品牌的动物商店:Animalear.com
2018/01/05 全球购物
任意存:BOXFUL
2018/05/21 全球购物
介绍一下游标
2012/01/10 面试题
文职个人求职信范文
2013/09/23 职场文书
护理学中专毕业生求职信
2013/11/11 职场文书
大学生毕业鉴定
2014/01/31 职场文书
银行求职信
2014/05/31 职场文书
司法所长先进事迹
2014/06/02 职场文书
党员四风自我剖析材料思想汇报
2014/09/13 职场文书
违反交通安全法检讨书
2014/10/24 职场文书
大学军训的体会
2014/11/08 职场文书
战马观后感
2015/06/08 职场文书
2015年统计员个人工作总结
2015/07/23 职场文书
公司员工奖惩制度
2015/08/04 职场文书
人民币使用说明书
2019/04/17 职场文书