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获取本机内网和外网ip地址的实现代码
Jun 01 NodeJs
async/await与promise(nodejs中的异步操作问题)
Mar 03 NodeJs
3分钟快速搭建nodejs本地服务器方法运行测试html/js
Apr 01 NodeJs
nodejs爬虫遇到的乱码问题汇总
Apr 07 NodeJs
nodejs入门教程六:express模块用法示例
Apr 24 NodeJs
nodejs实现简单的gulp打包
Dec 21 NodeJs
Nodejs模块载入运行原理
Feb 23 NodeJs
Mac下通过brew安装指定版本的nodejs教程
May 17 NodeJs
Nodejs让异步变成同步的方法
Mar 02 NodeJs
使用nodeJS中的fs模块对文件及目录进行读写,删除,追加,等操作详解
Feb 06 NodeJs
nodejs使用socket5进行代理请求的实现
Feb 21 NodeJs
一文秒懂nodejs中的异步编程
Jan 28 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 adodb操作mysql数据库
2009/03/19 PHP
php常用的安全过滤函数集锦
2014/10/09 PHP
thinkPHP框架中执行原生SQL语句的方法
2017/10/25 PHP
Laravel5.5 动态切换多语言的操作方式
2019/10/25 PHP
基于PHP实现短信验证码发送次数限制
2020/07/11 PHP
PHP array_reverse() 函数原理及实例解析
2020/07/14 PHP
借用Google的Javascript API Loader来加速你的网站
2009/01/28 Javascript
JavaScript中的闭包原理分析
2010/03/08 Javascript
jQuery EasyUI API 中文文档 - Spinner微调器使用
2011/10/21 Javascript
js中parseInt函数浅谈
2013/07/31 Javascript
JavaScript中实现依赖注入的思路分享
2015/01/15 Javascript
JSON格式的键盘编码对照表
2015/01/29 Javascript
基于JavaScript实现定时跳转到指定页面
2016/01/01 Javascript
基于Bootstrap3表格插件和分页插件实例详解
2016/05/17 Javascript
原生js封装二级城市下拉列表的实现代码
2016/06/16 Javascript
第十篇BootStrap轮播插件使用详解
2016/06/21 Javascript
AngularJS实现按钮提示与点击变色效果
2016/09/07 Javascript
Webpack的dll功能使用
2018/06/28 Javascript
超轻量级的js时间库miment使用解析
2019/08/02 Javascript
layui实现数据表格自定义数据项
2019/10/26 Javascript
浅析vue中的nextTick
2020/12/28 Vue.js
[02:55]2018DOTA2国际邀请赛勇士令状不朽珍藏Ⅲ饰品一览
2018/08/01 DOTA
[45:14]Optic vs VP 2018国际邀请赛淘汰赛BO3 第二场 8.24
2018/08/25 DOTA
Python基于socket模块实现UDP通信功能示例
2018/04/10 Python
Python中几种属性访问的区别与用法详解
2018/10/10 Python
Python类中的装饰器在当前类中的声明与调用详解
2020/04/15 Python
django 装饰器 检测登录状态操作
2020/07/02 Python
Python爬虫分析微博热搜关键词的实现代码
2021/02/22 Python
美国打印机墨水和碳粉购物网站:QuikShip Toner
2018/08/29 全球购物
Nike挪威官网:Nike.com (NO)
2018/11/26 全球购物
自我鉴定注意事项
2014/01/19 职场文书
金融管理专业毕业生求职信
2014/03/12 职场文书
2014组织生活会方案
2014/05/19 职场文书
个人学习党的群众路线教育实践活动心得体会
2014/11/05 职场文书
2016年大学自主招生自荐信范文
2015/03/24 职场文书
三十年同学聚会致辞
2015/07/28 职场文书