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 播放器 控制
Jan 22 Javascript
Prototype RegExp对象 学习
Jul 19 Javascript
javascript 四则运算精度修正函数代码
May 31 Javascript
让你的CSS像Jquery一样做筛选的实现方法
Jul 10 Javascript
基于jQuery的遍历同id元素 并响应事件的代码
Jun 14 Javascript
js导入导出excel(实例代码)
Nov 25 Javascript
js跳转页面方法实现汇总
Feb 11 Javascript
详解JavaScript基于面向对象之继承
Dec 13 Javascript
JS简单编号生成器实现方法(附demo源码下载)
Apr 05 Javascript
深入浅析vue组件间事件传递
Dec 29 Javascript
详解解决使用axios发送json后台接收不到的问题
Jun 27 Javascript
在 Vue-CLI 中引入 simple-mock实现简易的 API Mock 接口数据模拟
Nov 28 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 _autoload自动加载类与机制分析
2012/02/10 PHP
基于PHP静态类的原罪详解
2013/05/06 PHP
浅析PHP原理之变量分离/引用(Variables Separation)
2013/08/09 PHP
php使用Jpgraph绘制3D饼状图的方法
2015/06/10 PHP
PHP翻页跳转功能实现方法
2020/11/30 PHP
PHP下载文件的函数实例代码
2016/05/18 PHP
php在windows环境下获得cpu内存实时使用率(推荐)
2018/02/08 PHP
IE下使用cloneNode注意事项分享
2012/11/22 Javascript
JavaScript作用域链使用介绍
2013/08/29 Javascript
JQuery触发事件例如click
2013/09/11 Javascript
JS使用ajax方法获取指定url的head信息中指定字段值的方法
2015/03/24 Javascript
浅谈document.write()输出样式
2015/05/07 Javascript
分享jQuery封装好的一些常用操作
2016/07/28 Javascript
Canvas实现放射线动画效果
2017/02/15 Javascript
p5.js入门教程之键盘交互
2018/03/19 Javascript
微信小程序中时间戳和日期的相互转换问题
2018/07/09 Javascript
ng-alain表单使用方式详解
2018/07/10 Javascript
使用vue点击li,获取当前点击li父辈元素的属性值方法
2018/09/12 Javascript
详解使用JWT实现单点登录(完全跨域方案)
2019/08/02 Javascript
深入解析Python中函数的参数与作用域
2016/03/20 Python
如何在sae中设置django,让sae的工作环境跟本地python环境一致
2017/11/21 Python
基于python实现在excel中读取与生成随机数写入excel中
2018/01/04 Python
Linux下Python安装完成后使用pip命令的详细教程
2018/11/22 Python
Python 使用 Pillow 模块给图片添加文字水印的方法
2019/08/30 Python
JetBrains PyCharm(Community版本)的下载、安装和初步使用图文教程详解
2020/03/19 Python
解决django框架model中外键不落实到数据库问题
2020/05/20 Python
PyTorch-GPU加速实例
2020/06/23 Python
英国玛莎百货新西兰:Marks & Spencer New Zealand
2019/07/21 全球购物
远程学习的教学用品和家庭学习资源:Really Good Stuff
2020/04/27 全球购物
优秀团队获奖感言
2014/02/19 职场文书
运动会入场词50字
2014/02/20 职场文书
开国大典观后感
2015/06/04 职场文书
党员电教片《信仰》心得体会
2016/01/15 职场文书
spring cloud 配置中心客户端启动遇到的问题
2021/09/25 Java/Android
pycharm安装深度学习pytorch的d2l包失败问题解决
2022/03/25 Python
vue如何使用模拟的json数据查看效果
2022/03/31 Vue.js