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事件的监听与触发的理解分析
Feb 12 NodeJs
nodejs实现bigpipe异步加载页面方案
Jan 26 NodeJs
详解nodeJS中读写文件方法的区别
Mar 06 NodeJs
nodejs开发——express路由与中间件
Mar 24 NodeJs
详解nodejs中express搭建权限管理系统
Sep 15 NodeJs
NodeJs实现定时任务的示例代码
Dec 05 NodeJs
nodejs实现截取上传视频中一帧作为预览图片
Dec 10 NodeJs
nodejs结合Socket.IO实现的即时通讯功能详解
Jan 12 NodeJs
nodejs实现解析xml字符串为对象的方法示例
Mar 14 NodeJs
nodejs连接mysql数据库及基本知识点详解
Mar 20 NodeJs
用Electron写个带界面的nodejs爬虫的实现方法
Jan 29 NodeJs
NodeJS和浏览器中this关键字的不同之处
Mar 03 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 模拟 asp.net webFrom 按钮提交事件的思路及代码
2013/12/02 PHP
php简单socket服务器客户端代码实例
2015/05/18 PHP
[原创]php简单隔行变色功能实现代码
2016/07/09 PHP
漂亮的仿flash菜单,来自蓝色经典
2006/06/26 Javascript
学习YUI.Ext 第六天--关于树TreePanel(Part 2异步获取节点)
2007/03/10 Javascript
javascript 数组排序函数
2009/08/20 Javascript
js 纯数字不重复排列的另类方法
2010/07/17 Javascript
jQuery中验证表单提交方式及序列化表单内容的实现
2014/01/06 Javascript
js 获取元素所有兄弟节点的实现方法
2016/09/06 Javascript
使用JavaScript为一张图片设置备选路径的方法
2017/01/04 Javascript
利用JS实现简单的日期选择插件
2017/01/23 Javascript
react.js 获取真实的DOM节点实例(必看)
2017/04/17 Javascript
JavaScript内存泄漏的处理方式
2017/11/20 Javascript
详解React-Router中Url参数改变页面不刷新的解决办法
2018/05/08 Javascript
vue的过滤器filter实例详解
2018/09/17 Javascript
为什么要使用Vuex的介绍
2019/01/19 Javascript
对于防止按钮重复点击的尝试详解
2019/04/22 Javascript
微信小程序class封装http代码实例
2019/08/24 Javascript
微信小程序自定义导航栏(模板化)
2019/11/15 Javascript
JavaScript常用工具函数汇总(浏览器环境)
2020/09/17 Javascript
js实现缓动动画
2020/11/25 Javascript
[02:51]DOTA2战队出征照拍摄花絮 TI3明星化身时尚男模
2013/07/22 DOTA
使用Django的模版来配合字符串翻译工作
2015/07/27 Python
python嵌套函数使用外部函数变量的方法(Python2和Python3)
2016/01/31 Python
使用Python编写基于DHT协议的BT资源爬虫
2016/03/19 Python
Python使用Srapy框架爬虫模拟登陆并抓取知乎内容
2016/07/02 Python
高效测试用例组织算法pairwise之Python实现方法
2017/07/19 Python
Python实现的企业粉丝抽奖功能示例
2019/07/26 Python
Python Django 添加首页尾页上一页下一页代码实例
2019/08/21 Python
python如何实现DES加密
2020/09/21 Python
ProBikeKit新西兰:自行车套件,跑步和铁人三项装备
2017/04/05 全球购物
FORZIERI福喜利中国官网:奢侈品购物梦工厂
2019/05/03 全球购物
《藤野先生》教学反思
2014/02/19 职场文书
2014年煤矿工人工作总结
2014/12/08 职场文书
2016幼儿园毕业感言
2015/12/08 职场文书
Nginx跨域问题解析与解决
2022/08/05 Servers