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使用教程
Nov 23 NodeJs
nodejs redis 发布订阅机制封装实现方法及实例代码
Dec 15 NodeJs
详解nodejs 文本操作模块-fs模块(三)
Dec 22 NodeJs
nodejs实现发出蜂鸣声音(系统报警声)的方法
Jan 18 NodeJs
nodejs根据ip数组在百度地图中进行定位
Mar 06 NodeJs
初识NodeJS服务端开发入门(Express+MySQL)
Apr 07 NodeJs
nodejs个人博客开发第二步 入口文件
Apr 12 NodeJs
nodejs 最新版安装npm 的使用详解
Jan 18 NodeJs
Nodejs模块载入运行原理
Feb 23 NodeJs
NodeJs实现简单的爬虫功能案例分析
Dec 05 NodeJs
NodeJS实现同步的方法
Mar 02 NodeJs
NodeJS模块Buffer原理及使用方法解析
Nov 11 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 DOS攻击实现代码(附如何防范)
2012/05/29 PHP
PHP分多步骤填写发布信息的简单方法实例代码
2012/09/23 PHP
奉献出一个封装的curl函数 便于调用(抓数据专用)
2013/07/22 PHP
CI(CodeIgniter)框架介绍
2014/06/09 PHP
php约瑟夫问题解决关于处死犯人的算法
2015/03/23 PHP
关于php中一些字符串总结
2016/05/05 PHP
php-fpm重启导致的程序执行中断问题详解
2019/04/29 PHP
encode脚本和normal脚本混用的问题与解决方法
2007/03/08 Javascript
Javascript 同时提交多个Web表单的方法
2009/02/19 Javascript
Prototype 学习 工具函数学习($A方法)
2009/07/12 Javascript
javascript中的对象创建 实例附注释
2011/02/08 Javascript
jQuery操作input type=radio的实现代码
2012/06/14 Javascript
JQuery+Ajax无刷新分页的实例代码
2014/02/08 Javascript
基于JavaScript代码实现微信扫一扫下载APP
2015/12/30 Javascript
Google Maps基础及实例解析
2016/08/06 Javascript
微信小程序 scroll-view隐藏滚动条详解
2017/01/16 Javascript
详解vue 中使用 AJAX获取数据的方法
2017/01/18 Javascript
基于Angular.js实现的触摸滑动动画实例代码
2017/02/19 Javascript
使用socket.io实现简单聊天室案例
2018/01/02 Javascript
js基于canvas实现时钟组件
2021/02/07 Javascript
Python程序设计入门(2)变量类型简介
2014/06/16 Python
python中模块的__all__属性详解
2017/10/26 Python
Python3实现的画图及加载图片动画效果示例
2018/01/19 Python
Python模块搜索路径代码详解
2018/01/29 Python
Python利用scapy实现ARP欺骗的方法
2019/07/23 Python
对python中assert、isinstance的用法详解
2019/11/27 Python
python GUI库图形界面开发之PyQt5布局控件QHBoxLayout详细使用方法与实例
2020/03/06 Python
selenium+超级鹰实现模拟登录12306
2021/01/24 Python
英国乡村时尚和宠物用品专家:Pet & Country
2018/07/02 全球购物
Big Green Smile法国:领先的英国有机和天然产品在线商店
2021/01/02 全球购物
什么是Connection-oriented Protocol/Connectionless Protocol面向连接的协议/无连接协议
2012/09/06 面试题
简述网络文件系统NFS,并说明其作用
2016/10/19 面试题
2015欢度元旦标语口号
2014/12/09 职场文书
关于童年的读书笔记
2015/06/26 职场文书
优秀团员主要事迹材料
2015/11/05 职场文书
windows server2008 开启端口的实现方法
2022/06/25 Servers