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排序算法之希尔排序的2个实例
Apr 04 Javascript
JavaScript模拟实现键盘打字效果
Jun 29 Javascript
jQuery常用的一些技巧汇总
Mar 26 Javascript
EasyUI 中combotree 默认不能选择父节点的实现方法
Nov 07 Javascript
BootStrap CSS全局样式和表格样式源码解析
Jan 20 Javascript
jQuery选择器特殊字符与属性空格问题
Aug 14 jQuery
javascript填充默认头像方法
Feb 22 Javascript
vue实现同一个页面可以有多个router-view的方法
Sep 20 Javascript
详解可以用在VS Code中的正则表达式小技巧
May 14 Javascript
node省市区三级数据性能测评实例分析
Nov 06 Javascript
Vue数组响应式操作及高阶函数使用代码详解
Aug 01 Javascript
javascript实现打砖块小游戏(附完整源码)
Sep 18 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
最贵的咖啡是怎么产生的,它的风味怎么样?
2021/03/04 新手入门
无数据库的详细域名查询程序PHP版(5)
2006/10/09 PHP
php中通过curl模拟登陆discuz论坛的实现代码
2012/02/16 PHP
php实现约瑟夫问题的方法小结
2015/03/23 PHP
用javascript实现在小方框中浏览大图的代码
2007/08/14 Javascript
jQuery Tools Dateinput使用介绍
2012/07/14 Javascript
JS字符串处理实例代码
2013/08/05 Javascript
js判断字符是否是汉字的两种方法小结
2014/01/03 Javascript
JavaScript编程的10个实用小技巧
2014/04/18 Javascript
jQuery中nextUntil()方法用法实例
2015/01/07 Javascript
js获取元素外链样式的方法
2015/01/27 Javascript
Three.js学习之几何形状
2016/08/01 Javascript
关于js原型的面试题讲解
2016/09/25 Javascript
JavaScript使用FileReader实现图片上传预览效果
2020/03/27 Javascript
vue-ajax小封装实例
2017/09/18 Javascript
JS中数组与对象的遍历方法实例小结
2018/08/14 Javascript
vue实现多个元素或多个组件之间动画效果
2018/09/25 Javascript
利用原生JS实现data方法示例代码
2019/05/28 Javascript
JS script脚本中async和defer区别详解
2020/06/24 Javascript
python机器学习实战之树回归详解
2017/12/20 Python
Python基础教程之利用期物处理并发
2018/03/29 Python
python实现AES加密解密
2019/03/28 Python
pyqt5 comboBox获得下标、文本和事件选中函数的方法
2019/06/14 Python
python requests库爬取豆瓣电视剧数据并保存到本地详解
2019/08/10 Python
对Tensorflow中Device实例的生成和管理详解
2020/02/04 Python
python zip()函数的使用示例
2020/09/23 Python
python中time、datetime模块的使用
2020/12/14 Python
新西兰航空中国官网:Air New Zealand China
2018/07/24 全球购物
Notino芬兰:购买香水和化妆品
2019/04/15 全球购物
LN-CC日本:高端男装和女装的奢侈时尚目的地
2019/09/01 全球购物
股权转让协议书范本
2014/04/12 职场文书
我的中国梦演讲稿初中篇
2014/08/19 职场文书
买卖合同协议书范本
2014/10/18 职场文书
2014年医院工作总结
2014/11/20 职场文书
2015年远程教育工作总结
2015/05/20 职场文书
导游词之新疆-喀纳斯
2019/10/10 职场文书