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 相关文章推荐
14款NodeJS Web框架推荐
Jul 11 NodeJs
Nodejs为什么选择javascript为载体语言
Jan 13 NodeJs
浅谈Nodejs观察者模式
Oct 13 NodeJs
基于html5和nodejs相结合实现websocket即使通讯
Nov 19 NodeJs
Nodejs如何复制文件
Mar 09 NodeJs
浅谈Nodejs中的作用域问题
Dec 26 NodeJs
Nodejs实现短信验证码功能
Feb 09 NodeJs
NodeJs的fs读写删除移动监听
Apr 28 NodeJs
Nodejs中使用phantom将html转为pdf或图片格式的方法
Sep 18 NodeJs
nodejs结合socket.io实现websocket通信功能的方法
Jan 12 NodeJs
nodejs 最新版安装npm 的使用详解
Jan 18 NodeJs
nodejs提示:cross-device link not permitted, rename错误的解决方法
Jun 10 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 水平的题目
2007/05/30 PHP
PHP计划任务、定时执行任务的实现代码
2011/04/23 PHP
有关phpmailer的详细介绍及使用方法
2013/01/28 PHP
PHP中定义数组常量(array常量)的方法
2014/11/17 PHP
php中base_convert()进制数字转换函数实例
2014/11/20 PHP
php内存缓存实现方法
2015/01/24 PHP
php安装ssh2扩展的方法【Linux平台】
2016/07/20 PHP
ThinkPHP5与单元测试PHPUnit使用详解
2020/02/23 PHP
基于jquery的兼容各种浏览器的iframe自适应高度的脚本
2010/08/13 Javascript
Eclipse去除js(JavaScript)验证错误
2014/02/11 Javascript
极易被忽视的javascript面试题七问七答
2016/02/15 Javascript
深入对Vue.js $watch方法的理解
2017/03/20 Javascript
微信小程序三级联动选择器使用方法
2020/05/19 Javascript
jQuery实现鼠标响应式透明度渐变动画效果示例
2018/02/13 jQuery
Vue的watch和computed方法的使用及区别介绍
2018/09/06 Javascript
微信小程序动态增加按钮组件
2018/09/14 Javascript
js使用formData实现批量上传
2020/03/27 Javascript
javascript触发模拟鼠标点击事件
2019/06/26 Javascript
vue项目中锚点定位替代方式
2019/11/13 Javascript
element中的$confirm的使用
2020/04/26 Javascript
jQuery实现的解析本地 XML 文档操作示例
2020/04/30 jQuery
js代码实现轮播图
2020/05/04 Javascript
Python使用MYSQLDB实现从数据库中导出XML文件的方法
2015/05/11 Python
在DigitalOcean的服务器上部署flaskblog应用
2015/12/19 Python
Python PyQt5标准对话框用法示例
2017/08/23 Python
对python 生成拼接xml报文的示例详解
2018/12/28 Python
Python爬虫爬取、解析数据操作示例
2020/03/27 Python
python绘制趋势图的示例
2020/09/17 Python
详解HTML5布局和HTML5标签
2020/10/26 HTML / CSS
NBA德国官方网上商店:NBA Store德国
2018/04/13 全球购物
会计专业大学生职业生涯规划范文
2014/01/11 职场文书
《值日生》教学反思
2014/02/17 职场文书
离婚起诉状范本
2015/05/19 职场文书
2019年大学生暑期社会实践调查报告模板
2019/11/07 职场文书
解决python3安装pandas出错的问题
2021/05/20 Python
spring IOC容器的Bean管理XML自动装配过程
2022/05/30 Java/Android