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 this关键字使用分析
Oct 21 Javascript
cloudgamer出品ImageZoom 图片放大效果
Apr 01 Javascript
javascript 数组学习资料收集
Apr 11 Javascript
ExtJS 下拉多选框lovcombo
May 19 Javascript
用JQuery 判断某个属性是否存在hasAttr的解决方法
Apr 26 Javascript
JavaScript中实现Map的示例代码
Sep 09 Javascript
jQuery图片左右滚动代码 有左右按钮实例
Jun 20 Javascript
AngularJS之依赖注入模拟实现
Aug 19 Javascript
Query常用DIV操作获取和设置长度宽度的实现方法
Sep 19 Javascript
AngularJS动态生成select下拉框的方法实例
Nov 17 Javascript
vue-cli+webpack项目打包到服务器后,ttf字体找不到的解决操作
Aug 28 Javascript
IDEA配置jQuery, $符号不再显示黄色波浪线的问题
Oct 09 jQuery
关于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/02/28 无线电
window+nginx+php环境配置 附配置搭配说明
2010/12/29 PHP
详谈PHP文件目录基础操作
2014/11/11 PHP
php第一次无法获取cookie问题处理
2014/12/15 PHP
php自定义加密与解密程序实例
2014/12/31 PHP
ioncube_loader_win_5.2.dll的错误解决方法
2015/01/04 PHP
Symfony2针对输入时间进行查询的方法分析
2017/06/28 PHP
phpQuery采集网页实现代码实例
2020/04/02 PHP
splice slice区别
2006/10/09 Javascript
jQuery实现数秒后自动提交form的方法
2015/03/05 Javascript
jQuery中trigger()与bind()用法分析
2015/12/18 Javascript
自动完成的搜索框javascript实现
2016/02/26 Javascript
JavaScript实现时间倒计时跳转(推荐)
2016/06/28 Javascript
bootstrap学习使用(导航条、下拉菜单、轮播、栅格布局等)
2016/12/01 Javascript
微信小程序实战之自定义抽屉菜单(7)
2017/04/18 Javascript
vue移动端轻量级的轮播组件实现代码
2018/07/12 Javascript
[07:20]2014DOTA2西雅图国际邀请赛 选手讲解积分赛第二天
2014/07/11 DOTA
浅谈python中的占位符
2017/11/09 Python
利用django-suit模板添加自定义的菜单、页面及设置访问权限
2018/07/13 Python
详解pytorch 0.4.0迁移指南
2019/06/16 Python
python获取指定日期范围内的每一天,每个月,每季度的方法
2019/08/08 Python
python pycharm的安装及其使用
2019/10/11 Python
Python学习之路安装pycharm的教程详解
2020/06/17 Python
python3中数组逆序输出方法
2020/12/01 Python
英国男士时尚网站:Dandy Fellow
2018/02/09 全球购物
Cocopanda波兰:购买化妆品、护肤品、护发和香水
2020/05/25 全球购物
物流管理毕业生自荐信
2013/10/24 职场文书
纪念建党演讲稿范文
2014/01/13 职场文书
大家检讨书5000字
2014/02/03 职场文书
六五普法规划实施方案
2014/03/21 职场文书
大学生村官演讲稿
2014/04/25 职场文书
体育口号大全
2014/06/18 职场文书
总经理助理岗位职责范本
2014/07/20 职场文书
教师工作自我鉴定范文
2014/09/14 职场文书
解决python3安装pandas出错的问题
2021/05/20 Python
使用Ajax实现无刷新上传文件
2022/04/12 Javascript