odejs回调加超时限制两种实现方法

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}`);
});
}

  模块调用方法:

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回调加超时限制两种实现方法的更多相关文章

  1. C模块回调Lua函数的两种方法

    作者:ani_di 版权所有,转载务必保留此链接 http://blog.csdn.net/ani_di C模块回调Lua函数的两种方法 lua和C通过虚拟栈这种交互方式简单而又可靠,缺点就是C做栈平 ...

  2. 关于PHP的加载类操作以及其他两种魔术方法应用

    <?php 加载类//include("./Ren.class.php");//include "./Ren.class.php";include_onc ...

  3. ChemDraw加键的两种方法

    绘制化学结构离不开9种ChemDraw键工具,键工具在绘制过程中提供了最大的使用优势,这种优势体现在键角.键长的绘制,故很有必要学习相关的ChemDraw使用技巧.本ChemDraw教程将具体介绍在C ...

  4. 两种js方法发起微信支付:WeixinJSBridge,wx.chooseWXPay区别

    原文链接:https://www.2cto.com/weixin/201507/412752.html 1.为什么会有两种JS方法可以发起微信支付? 当你登陆微信公众号之后,左边有两个菜单栏,一个是微 ...

  5. 史上最全的CSS hack方式一览 jQuery 图片轮播的代码分离 JQuery中的动画 C#中Trim()、TrimStart()、TrimEnd()的用法 marquee 标签的使用详情 js鼠标事件 js添加遮罩层 页面上通过地址栏传值时出现乱码的两种解决方法 ref和out的区别在c#中 总结

    史上最全的CSS hack方式一览 2013年09月28日 15:57:08 阅读数:175473 做前端多年,虽然不是经常需要hack,但是我们经常会遇到各浏览器表现不一致的情况.基于此,某些情况我 ...

  6. angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用

    今天我们要讲的是ng2的路由系统. 例子

  7. 两种Ajax方法

    两种Ajax方法 Ajax是一种用于快速创建动态网页的技术,他通过在后台与服务器进行少量的数据交换,可以实现网页的异步更新,不需要像传统网页那样重新加载页面也可以做到对网页的某部分作出更新,现在这项技 ...

  8. Linux系统中存储设备的两种表示方法

    转:https://blog.csdn.net/holybin/article/details/38637381 一.对于IDE接口的硬盘的两种表示方法: 1.IDE接口硬盘,对于整块硬盘的两种表示方 ...

  9. win7系统不能用telnet命令的两种解决方法

    电脑专业人员对telnet命令都不陌生了,Telnet当成一种通信协议,在日常工作中,经常面对网络问题的人都会用到telnet命令,因为简单有效,可以帮助更快的找出问题.要是在使用过程中碰到win7纯 ...

随机推荐

  1. eclipse 自定义代码块设置(代码模板)

    eclipse设置自定义代码模板 window -> show View -> other -> Templates 原来main模板 修改模板 再次插入

  2. 【转】 WordPress数据库及各表结构分析

    默认WordPress一共有以下11个表.这里加上了默认的表前缀 wp_ . wp_commentmeta:存储评论的元数据wp_comments:存储评论wp_links:存储友情链接(Blogro ...

  3. 移动端 vue + mintUI 实现头部页签切换,按需加载~

    记录~记录~~有时候,我们会遇到一个页面有两个页签切换需求,但是为了避免同时加载两个页面,我们要做到的就是当前进入的是那个页面,就先加载哪一个页面,并且也不会造成浏览器地址的变化.一开始我使用的方法是 ...

  4. 洛谷P1131 时态同步

    题意: 给一个n点的树,每条边都有边权,问从根出发需要增加多少长度,使得最终的儿子到根的距离是一样的 思路: 上来一个思路wa了3次,看完题解之后,又一次豁然开朗…… orz #include< ...

  5. (2)Linux Java环境变量安装

    install default JRE/JDK Installing Java with apt-get is easy. First, update the package index: sudo ...

  6. Hibernate学习(七)

    Hibernate缓存 1.一级缓存:Session 级别的缓存 2.二级缓存: SessionFactory 级别的缓存 3.查询缓存:需二级缓存的支持,查询缓存依赖二级缓存 一级缓存 1.依赖于 ...

  7. 一大波新款iPhone跟安卓厂商抢夺5G市场

    据外媒最新报道称,苹果已经基本完成了今年iPhone的推新阵容,其发布的多款新机中,将涵盖399美元-1149美元的售价区间,特别是5G手机,起步价可能会很亲民,其目的在于进一步占据市场. 今年苹果将 ...

  8. SVN中如何创建共享文件夹

    http://wenku.baidu.com/link?url=E8tC1idSdTABc3JzyqGYF8OXakDTIF_yWp8BvFqSX5dgcpkbm8Z57ursZtLpjmQAEABM ...

  9. java编译中出现了Exception in thread “main" java.lang.UnsupportedClassVersionError

    这个问题确实是由较高版本的JDK编译的java class文件试图在较低版本的JVM上运行产生的错误. 1.解决措施就是保证jvm(java命令)和jdk(javac命令)版本一致.如果是linux版 ...

  10. Hive的学习之路(理论篇)

    一.Hive介绍 Apache官网给出的logo,一半是Hadoop大象的头,一半是蜜蜂的身体,也是寓意着它是基于Hadoop,哈哈,纯属个人理解,进入正题. Hive是基于Hadoop的一个数据仓库 ...