node.js多个异步过程中判断执行是否完成的解决方案


Posted in Javascript onDecember 10, 2017

前言

本文主要给大家介绍了关于node.js多个异步过程中判断执行是否完成的相关内容,可能这样说大家不是很明白,下面来一起看看详细的介绍吧。

场景:

想请求量较大的网络数据,比如想获取1000条结果,但数据处理速度慢,有超时的风险,可以分成10次处理,每次处理100条;所有请求完成后再统一进行处理。

这样的应用场景,可以这样处理:

方案一:判断请求到的数据条目

// 模拟网络请求
function fetch(url, callback) {
 setTimeout(function (){
 callback(null, {
  subjects: [{
   data: Math.round(Math.random() * 100)
  }]
  });
 }, 2000);
}
// 实现方案1
function multiTask_1 () {
 var arr = [];
 var baseUrl = 'https://api.douban.com/v2/movie/top250';
 for (var start = 0; start < 10; start++) {
 var url = baseUrl + '?start=' + start + "&count=1";
  fetch(url, function(error, res) {
  var data = res.subjects;
  arr = arr.concat(data);
  // 调用完成后统一处理
  if (arr.length === 10) {
   console.log(arr);
  }
 });
 }
}

将运行结果用arr.length来判断,如果arr.length不像我们期望的那样,比如由于网络传输或者处理异常,少一条,那么我们将无法做后续的处理。这种处理方式强业务耦合;不具有普适性。

方案二:判断异步过程执行次数

// 方案2
function multiTask_2 () {
 var taskWatcher = 0;
 var arr = [];
 var baseUrl = 'https://api.douban.com/v2/movie/top250';
 for (var start = 0; start < 10; start++) {
 taskWatcher++;
 var url = baseUrl + '?start=' + start + "&count=1";
 fetch(url, function(error, res) {
  var data = res.subjects;
  arr = arr.concat(data);
  taskWatcher--;
  if (taskWatcher === 0) {
   console.log(arr);
  }
 });
 }
}

方案2 的判断条件,这里的 taskWatcher 充当异步任务执行情况的观察员,仅与异步过程的调用次数有关,且与其他处理过程无关。那有没有其他方案呢

方案三:Promise.all()

Promise.all(iterable) 方法返回一个 Promise, 它将在上述可迭代对象中的所有 Promise 被 resolve 之后被 resolve,或者在任一 Promise 被 reject 后被 reject。

function multiTask_3 () {
 // var taskWatcher = 0;
 var taskStack = [];
 var arr = [];
 var baseUrl = 'https://api.douban.com/v2/movie/top250';
 for (var start = 0; start < 10; start++) {
 taskStack.push(
  new Promise((resolve, reject) => {
  var url = baseUrl + '?start=' + start + "&count=1";
  fetch(url, function(error, res) {
   var data = res.subjects;
   arr = arr.concat(data);
   resolve();
  });
  })
 );
 }
 Promise.all(taskStack).then(function () {
 console.log(arr);
 });
}

这种方式更具有通用性,如果异步任务类型不同,也可以用这种方式来解决。不过应当注意reject的处理。避免其对最终处理的影响。

方案四: EventProxy

EventProxy是朴灵写的,https://github.com/JacksonTian/eventproxy

var ep = new EventProxy();
 var arr = [];
 ep.after('fetchData', 10, function (list) {
 list.forEach(function(item){
  arr = arr.concat(item); 
 });
 console.log(arr);
 });
 var baseUrl = 'https://api.douban.com/v2/movie/top250';
 for (var start = 0; start < 10; start++) {
 var url = baseUrl + '?start=' + start + "&count=1";
  fetch(url, function(error, res) {
  var data = res.subjects;
  ep.emit('fetchData', data);
 });
 }

EventProxy基于事件订阅/发布模式,这里的after 方法可以侦听多次事件,回调中保存了多次异步任务的数据结果的数组;除此之外EventProxy还支持多个不同事件的侦听和处理。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
Ext JS Grid在IE6 下宽度的问题解决方法
Feb 15 Javascript
JS 操作符整理[推荐收藏]
Nov 15 Javascript
jquery.blockUI.js上传滚动等待效果实现思路及代码
Mar 18 Javascript
js图片自动轮播代码分享(js图片轮播)
May 06 Javascript
html的DOM中Event对象onblur事件用法实例
Jan 21 Javascript
jquery简单实现网页层的展开与收缩效果
Aug 07 Javascript
原生js图片轮播效果实现代码
Oct 19 Javascript
关于Promise 异步编程的实例讲解
Sep 01 Javascript
vue2.0 实现导航守卫(路由守卫)
May 21 Javascript
node.js域名解析实现方法详解
Nov 05 Javascript
vue中实现点击按钮滚动到页面对应位置的方法(使用c3平滑属性实现)
Dec 29 Javascript
javascript实现电商放大镜效果
Nov 23 Javascript
关于react中组件通信的几种方式详解
Dec 10 #Javascript
vue项目中v-model父子组件通信的实现详解
Dec 10 #Javascript
Angular项目从新建、打包到nginx部署全过程记录
Dec 09 #Javascript
利用ES6实现单例模式及其应用详解
Dec 09 #Javascript
利用node.js如何创建子进程详解
Dec 09 #Javascript
微信小程序使用slider设置数据值及switch开关组件功能【附源码下载】
Dec 09 #Javascript
微信小程序实现action-sheet弹出底部菜单功能【附源码下载】
Dec 09 #Javascript
You might like
德生S2000南麂列岛台湾FM收听记录
2021/03/02 无线电
php在字符串中查找另一个字符串
2008/11/19 PHP
php操作sqlserver关于时间日期读取的小小见解
2009/11/29 PHP
thinkphp框架类库扩展操作示例
2019/11/26 PHP
javascript模拟评分控件实现方法
2015/05/13 Javascript
jQuery调用WebMethod(PageMethod) NET2.0的方法
2016/04/15 Javascript
jQuery实现简洁的轮播图效果实例
2016/09/07 Javascript
利用js来实现缩略语列表、文献来源链接和快捷键列表
2016/12/16 Javascript
jquery实现表单获取短信验证码代码
2017/03/13 Javascript
js断点调试心得分享(必看篇)
2017/12/08 Javascript
Vue实现底部侧边工具栏的实例代码
2018/09/03 Javascript
详解vue项目中调用百度地图API使用方法
2019/04/25 Javascript
vue组件添加事件@click.native操作
2020/10/30 Javascript
[15:35]教你分分钟做大人:天怒法师
2014/10/30 DOTA
[56:35]DOTA2上海特级锦标赛C组小组赛#1 OG VS Archon第二局
2016/02/27 DOTA
[54:41]2018DOTA2亚洲邀请赛3月30日 小组赛B组 VGJ.T VS paiN
2018/03/31 DOTA
Python pyinotify日志监控系统处理日志的方法
2018/03/08 Python
windows下添加Python环境变量的方法汇总
2018/05/14 Python
Python延时操作实现方法示例
2018/08/14 Python
Python 转换RGB颜色值的示例代码
2019/10/13 Python
CSS3常用的几种颜色渐变模式总结
2016/11/18 HTML / CSS
Microsoft Advertising美国:微软搜索广告
2019/05/01 全球购物
Ashford台湾:以折扣价提供奢华的男女用表款
2019/12/04 全球购物
您的时尚,您的生活方式:DTLR Villa
2019/12/25 全球购物
说一下mysql, oracle等常见数据库的分页实现方案
2012/09/29 面试题
怎样在 Applet 中建立自己的菜单(MenuBar/Menu)?
2012/06/20 面试题
总裁办公室主任职责
2014/01/02 职场文书
车间统计员岗位职责
2014/01/05 职场文书
办公室员工岗位工作职责
2014/03/10 职场文书
《三顾茅庐》教学反思
2014/04/10 职场文书
幼儿园中班上学期评语
2014/04/18 职场文书
教师节主持词开场白
2015/05/29 职场文书
2015年挂职锻炼个人总结
2015/10/22 职场文书
中学生打架《检讨书》范文
2019/08/12 职场文书
MySQL系列之十 MySQL事务隔离实现并发控制
2021/07/02 MySQL
mongoDB数据库索引快速入门指南
2022/03/23 MongoDB