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 提示‘xxx’ 不是内部或外部命令解决方法
Nov 20 NodeJs
轻松创建nodejs服务器(1):一个简单nodejs服务器例子
Dec 18 NodeJs
nodeJS代码实现计算交社保是否合适
Mar 09 NodeJs
Nodejs初级阶段之express
Nov 23 NodeJs
详解nodejs 文本操作模块-fs模块(一)
Dec 22 NodeJs
nodejs集成sqlite使用示例
Jun 05 NodeJs
Nodejs之http的表单提交
Jul 07 NodeJs
nodejs构建本地web测试服务器 如何解决访问静态资源问题
Jul 14 NodeJs
nodejs 搭建简易服务器的图文教程(推荐)
Jul 18 NodeJs
nodejs微信扫码支付功能实现
Feb 17 NodeJs
CentOS7中源码编译安装NodeJS的完整步骤
Oct 13 NodeJs
nodejs制作小爬虫功能示例
Feb 24 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
桌面中心(三)修改数据库
2006/10/09 PHP
php文件上传、下载和删除示例
2020/08/28 PHP
基于jQuery的动态增删改查表格信息,可左键/右键提示(原创自Zjmainstay)
2012/07/31 Javascript
JavaScript实现的石头剪刀布游戏源码分享
2014/08/22 Javascript
PHP中使用微秒计算脚本执行时间例子
2014/11/19 Javascript
jquery checkbox无法用attr()二次勾选问题的解决方法
2016/07/22 Javascript
如何理解Vue的render函数的具体用法
2017/08/30 Javascript
jQuery中元素选择器(element)简单用法示例
2018/05/14 jQuery
angular 未登录状态拦截路由跳转的方法
2018/10/09 Javascript
微信小程序学习笔记之表单提交与PHP后台数据交互处理图文详解
2019/03/28 Javascript
简单了解小程序+node梳理登陆流程
2019/06/24 Javascript
浅探express路由和中间件的实现
2019/09/30 Javascript
vue-cli点击实现全屏功能
2020/03/07 Javascript
javascript设计模式 ? 访问者模式原理与用法实例分析
2020/04/26 Javascript
Node.js API详解之 zlib模块用法分析
2020/05/19 Javascript
把大数据数字口语化(python与js)两种实现
2013/02/21 Python
Linux中安装Python的交互式解释器IPython的教程
2016/06/13 Python
使用Python读写及压缩和解压缩文件的示例
2016/07/08 Python
解决Ubuntu pip 安装 mysql-python包出错的问题
2018/06/11 Python
Python实现的文轩网爬虫完整示例
2019/05/16 Python
python 猴子补丁(monkey patch)
2019/06/26 Python
Django 对象关系映射(ORM)源码详解
2019/08/06 Python
Python脚本去除文件的只读性操作
2020/03/05 Python
Python logging模块原理解析及应用
2020/08/13 Python
Cotton On美国网站:澳洲时装连锁品牌
2016/10/25 全球购物
美国折衷生活方式品牌:Robert Graham
2018/07/13 全球购物
Lowe’s加拿大:家居装修、翻新和五金店
2019/12/06 全球购物
ajax是什么及其工作原理
2012/02/08 面试题
土木工程师岗位职责
2013/11/24 职场文书
主题婚礼策划方案
2014/02/10 职场文书
市场营销专业自荐书
2014/06/10 职场文书
商场消防安全责任书
2014/07/29 职场文书
小升初自荐信范文
2015/03/05 职场文书
2015年食品安全工作总结
2015/05/15 职场文书
Docker下安装Oracle19c
2022/04/13 Servers
最新动漫情报:2022年7月新番定档超过30部, OVERLORD骨王第四季也在其中噢
2022/05/04 日漫