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 相关文章推荐
动态为事件添加js代码示例
Feb 15 Javascript
有关DOM元素与事件的3个谜题
Nov 11 Javascript
判断javascript的数据类型(示例代码)
Dec 11 Javascript
玩转方法:call和apply
May 08 Javascript
谷歌地图打不开的解决办法
Aug 07 Javascript
jquery比较简洁的软键盘特效实现方法
Mar 19 Javascript
JavaScript中的this关键字使用详解
Aug 14 Javascript
JS实现选中当前菜单后高亮显示的导航条效果
Oct 15 Javascript
jQuery简单实现上下,左右滑动的方法
Jun 01 Javascript
ionic 3.0+ 项目搭建运行环境的教程
Aug 09 Javascript
nuxt 自定义 auth 中间件实现令牌的持久化操作
Nov 05 Javascript
Moment的feature导致线上bug解决分析
Sep 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
PHP 字符串编码截取函数(兼容utf-8和gb2312)
2009/05/02 PHP
PHP的单引号和双引号 字符串效率
2009/05/27 PHP
PHP json_decode函数详细解析
2014/02/17 PHP
Jquery Ajax学习实例4 向WebService发出请求,返回实体对象的异步调用
2010/03/16 Javascript
javascript+iframe 实现无刷新载入整页的代码
2010/03/17 Javascript
jQuery实现的仿select功能代码
2015/08/19 Javascript
整理Javascript基础语法学习笔记
2015/11/29 Javascript
jquery编写Tab选项卡滚动导航切换特效
2020/07/17 Javascript
全面解析JavaScript中的valueOf与toString方法(推荐)
2016/06/14 Javascript
JavaScript获取短信验证码(周期性)
2016/12/29 Javascript
微信小程序实现轮播图效果
2017/09/07 Javascript
node.js支持多用户web终端实现及安全方案
2017/11/29 Javascript
Element Table的row-class-name无效与动态高亮显示选中行背景色
2018/11/30 Javascript
使用Vue父子组件通信实现todolist的功能示例代码
2019/04/11 Javascript
使用React手写一个对话框或模态框的方法示例
2019/04/25 Javascript
js实现页面多个日期时间倒计时效果
2019/06/20 Javascript
tweenjs缓动算法的使用实例分析
2019/08/26 Javascript
微信小程序仿通讯录功能
2020/04/09 Javascript
js+canvas实现刮刮奖功能
2020/09/13 Javascript
在Keras中实现保存和加载权重及模型结构
2020/06/15 Python
python 浮点数四舍五入需要注意的地方
2020/08/18 Python
Python Selenium实现无可视化界面过程解析
2020/08/25 Python
怎么解决pycharm license Acti的方法
2020/10/28 Python
通过Django Admin+HttpRunner1.5.6实现简易接口测试平台
2020/11/11 Python
HTML5 video标签(播放器)学习笔记(二):播放控制
2015/04/24 HTML / CSS
浅谈amaze-ui中datepicker和datetimepicker注意的几点
2020/08/21 HTML / CSS
美国知名的隐形眼镜电商:Contacts America
2019/11/19 全球购物
为您搜罗全球潮流時尚品牌:HBX
2019/12/04 全球购物
建筑专业毕业生求职信
2014/09/30 职场文书
群众路线领导班子整改方案
2014/10/25 职场文书
文案策划岗位职责
2015/02/11 职场文书
爱国主义影片观后感
2015/06/18 职场文书
董事长新年致辞
2015/07/29 职场文书
小学生作文写作技巧100例,非常实用!
2019/07/08 职场文书
简单聊聊Vue中的计算属性和属性侦听
2021/10/05 Vue.js
浅谈GO中的Channel以及死锁的造成
2022/03/18 Golang