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 相关文章推荐
JavaScript高级程序设计
Dec 29 Javascript
Jquery 最近浏览过的商品的功能实现代码
May 14 Javascript
5个数组Array方法: indexOf、filter、forEach、map、reduce使用实例
Jan 29 Javascript
Jquery+Ajax+PHP+MySQL实现分类列表管理(下)
Oct 28 Javascript
js图片上传前预览功能(兼容所有浏览器)
Aug 24 Javascript
BootStrap框架个人总结(bootstrap框架、导航条、下拉菜单、轮播广告carousel、栅格系统布局、标签页tabs、模态框、菜单定位)
Dec 01 Javascript
如何通过非数字与字符的方式实现PHP WebShell详解
Jul 02 Javascript
vue 运用mock数据的示例代码
Nov 07 Javascript
移动端图片上传旋转、压缩问题的方法
Oct 16 Javascript
vue数据更新UI不刷新显示的解决办法
Aug 06 Javascript
vue设置默认首页的操作
Aug 12 Javascript
Vue自定义铃声提示音组件的实现
Jan 22 Vue.js
关于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
五款常用mysql slow log分析工具的比较分析
2011/05/22 PHP
php 文件上传类代码
2011/08/06 PHP
PHP图像处理之imagecreate、imagedestroy函数介绍
2014/11/19 PHP
Javascript new关键字的玄机 以及其它
2010/08/25 Javascript
jQuery下扩展插件和拓展函数的写法(匿名函数使用的典型例子)
2010/10/20 Javascript
基于jquery实现的鼠标滑过按钮改变背景图片
2011/07/15 Javascript
jQuery表格插件ParamQuery简单使用方法示例
2013/12/05 Javascript
js使用Array.prototype.sort()对数组对象排序的方法
2015/01/28 Javascript
jQuery插件Tooltipster实现漂亮的工具提示
2015/04/12 Javascript
JavaScript中的toUTCString()方法使用详解
2015/06/12 Javascript
js实现具有高亮显示效果的多级菜单代码
2015/09/01 Javascript
最简单的JavaScript图片轮播代码(两种方法)
2015/12/18 Javascript
jQuery+PHP实现微信转盘抽奖功能的方法
2016/05/25 Javascript
Jquery ajax请求导出Excel表格的实现代码
2016/06/08 Javascript
特殊日期提示功能的实现方法
2016/06/16 Javascript
jQuery实现限制文本框的输入长度
2017/01/11 Javascript
vue-router路由简单案例介绍
2017/02/21 Javascript
jQuery编写textarea输入字数限制代码
2017/03/23 jQuery
Vue学习笔记进阶篇之vue-cli安装及介绍
2017/07/18 Javascript
AI小程序之语音听写来了,十分钟掌握百度大脑语音听写全攻略
2020/03/13 Javascript
详解js中的几种常用设计模式
2020/07/16 Javascript
[56:47]Ti4 循环赛第三日 iG vs Liquid
2014/07/12 DOTA
使用Python爬取最好大学网大学排名
2018/02/24 Python
python 字典的打印实现
2019/09/26 Python
python cv2截取不规则区域图片实例
2019/12/21 Python
python网络编程之五子棋游戏
2020/05/14 Python
python中的django是做什么的
2020/07/31 Python
彻底解决Python包下载慢问题
2020/11/15 Python
德国低价购买灯具和家具网站:Style-home.de
2016/11/25 全球购物
Calzedonia美国官网:意大利风格袜子、打底裤和沙滩装
2018/07/19 全球购物
MYSQL支持事务吗
2013/08/09 面试题
2014年会计个人工作总结
2014/11/24 职场文书
个人求职信格式范文
2015/03/20 职场文书
PyQt5爬取12306车票信息程序的实现
2021/05/14 Python
详解vue身份认证管理和租户管理
2021/05/25 Vue.js
python关于集合的知识案例详解
2021/05/30 Python