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 相关文章推荐
jquery分页插件AmSetPager(自写)
Apr 15 Javascript
贴近用户体验的Jquery日期、时间选择插件
Aug 19 Javascript
JavaScript实现的多种鼠标拖放效果
Nov 03 Javascript
基于jQuery实现的设置文本区域的光标位置
Jun 15 jQuery
快速解决Vue项目在IE浏览器中显示空白的问题
Sep 04 Javascript
node.js的Express服务器基本使用教程
Jan 09 Javascript
angular 实现同步验证器跨字段验证的方法
Apr 11 Javascript
Vue动态组件和异步组件原理详解
May 06 Javascript
vue中实现上传文件给后台实例详解
Aug 22 Javascript
vuex vue简单使用知识点总结
Aug 29 Javascript
js中的面向对象之对象常见创建方法详解
Dec 16 Javascript
JavaScript事件概念详解(区分静态注册和动态注册)
Feb 05 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
第十二节 类的自动加载 [12]
2006/10/09 PHP
php 计划任务 检测用户连接状态
2012/03/29 PHP
PHP字符串的连接的简单实例
2013/12/30 PHP
php 利用socket发送HTTP请求(GET,POST)
2015/08/24 PHP
php表单处理操作
2017/11/16 PHP
PHP设计模式之适配器模式原理与用法分析
2018/04/25 PHP
Laravel事件监听器用法实例分析
2019/03/12 PHP
php 多继承的几种常见实现方法示例
2019/11/18 PHP
JavaScript 学习笔记(十一)
2010/01/19 Javascript
css值转换成数值请抛弃parseInt
2011/10/24 Javascript
JavaScript获取Url里的参数
2014/12/18 Javascript
js中数组的常用方法小结
2016/12/30 Javascript
NodeJS遍历文件生产文件列表功能示例
2017/01/22 NodeJs
微信小程序实战之自定义模态弹窗(8)
2017/04/18 Javascript
js微信应用场景之微信音乐相册案例分享
2017/08/11 Javascript
element-ui table span-method(行合并)的实现代码
2018/12/20 Javascript
JavaScript 继承 封装 多态实现及原理详解
2019/07/29 Javascript
nodejs对项目下所有空文件夹创建gitkeep的方法
2019/08/02 NodeJs
[20:21]《一刀刀一天》第十六期:TI国际邀请赛正式打响,总奖金超过550万
2014/05/23 DOTA
举例区分Python中的浅复制与深复制
2015/07/02 Python
使用pyshp包进行shapefile文件修改的例子
2019/12/06 Python
PyTorch笔记之scatter()函数的使用
2020/02/12 Python
Python操作MongoDb数据库流程详解
2020/03/05 Python
Python semaphore evevt生产者消费者模型原理解析
2020/03/18 Python
解析Tensorflow之MNIST的使用
2020/06/30 Python
导致python中import错误的原因是什么
2020/07/01 Python
详解tensorflow之过拟合问题实战
2020/11/01 Python
Matlab使用Plot函数实现数据动态显示方法总结
2021/02/25 Python
检测浏览器是否支持html5视频的代码
2013/03/28 HTML / CSS
FC-Moto丹麦:欧洲最大的摩托车服装和头盔商店之一
2019/08/20 全球购物
民生工程实施方案
2014/03/22 职场文书
2014年毕业演讲稿范文
2014/05/13 职场文书
大学生优秀班干部事迹材料
2014/05/26 职场文书
个人授权委托书格式
2014/08/30 职场文书
2016年心理学教育培训学习心得体会
2016/01/12 职场文书
python-opencv 中值滤波{cv2.medianBlur(src, ksize)}的用法
2021/06/05 Python