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 相关文章推荐
用js实现的自定义的对话框的实现代码
Mar 21 Javascript
jQuery实现长文字部分显示代码
May 13 Javascript
简单几行JS Code实现IE邮件转发新浪微博
Jul 03 Javascript
浏览器窗口大小变化时使用resize事件对框架不起作用的解决方法
May 11 Javascript
javascript实现单击和双击并存的方法
Dec 13 Javascript
浅谈js多维数组和hash数组定义和使用
Jul 27 Javascript
jQuery Validate验证表单时多个name相同的元素只验证第一个的解决方法
Dec 24 Javascript
vue服务端渲染的实例代码
Aug 28 Javascript
vue 使用Jade模板写html,stylus写css的方法
Feb 23 Javascript
Node.js静态服务器的实现方法
Feb 28 Javascript
js实现类选择器和name属性选择器的示例步骤
Feb 07 Javascript
Nest.js参数校验和自定义返回数据格式详解
Mar 29 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 XML error parsing SOAP payload on line 1
2010/06/17 PHP
php获取后台Job管理的实现代码
2011/06/10 PHP
Yii2增删改查之查询 where参数详细介绍
2016/08/08 PHP
Laravel自动生成UUID,从建表到使用详解
2019/10/24 PHP
JS等比例缩小图片尺寸的实例
2013/02/27 Javascript
使用ImageMagick进行图片缩放、合成与裁剪(js+python)
2013/09/16 Javascript
jquery实现类似淘宝星星评分功能实例
2014/09/12 Javascript
JQuery中ajax方法访问web服务实例
2015/07/18 Javascript
javascript模拟C#格式化字符串
2015/08/26 Javascript
javascript实现uploadify上传格式以及个数限制
2015/11/23 Javascript
node.js文件上传处理示例
2016/10/27 Javascript
vue-cli如何添加less 以及sass
2017/07/06 Javascript
JavaScript中各数制转换全面总结
2017/08/21 Javascript
AngularJS 控制器 controller的详解
2017/10/17 Javascript
jQuery实现checkbox即点即改批量删除及中间遇到的坑
2017/11/11 jQuery
解决echarts的多个折现数据出现坐标和值对不上的问题
2018/12/28 Javascript
[48:53]2014 DOTA2华西杯精英邀请赛 5 25 LGD VS VG第一场
2014/05/26 DOTA
[53:10]完美世界DOTA2联赛决赛日 FTD vs GXR 第二场 11.08
2020/11/11 DOTA
树莓派中python获取GY-85九轴模块信息示例
2013/12/05 Python
python列表操作实例
2015/01/14 Python
Python信息抽取之乱码解决办法
2017/06/29 Python
Python使用matplotlib实现绘制自定义图形功能示例
2018/01/18 Python
对python中执行DOS命令的3种方法总结
2018/05/12 Python
Python定时发送消息的脚本:每天跟你女朋友说晚安
2018/10/21 Python
在win10和linux上分别安装Python虚拟环境的方法步骤
2019/05/09 Python
深入浅析Python中的迭代器
2019/06/04 Python
关于 Python opencv 使用中的 ValueError: too many values to unpack
2019/06/28 Python
Python获取当前脚本文件夹(Script)的绝对路径方法代码
2019/08/27 Python
python3 使用traceback定位异常实例
2020/03/09 Python
兰蔻美国官网:Lancome美国
2017/04/25 全球购物
商场促销活动方案
2014/02/08 职场文书
安全在我心中演讲稿
2014/09/01 职场文书
2015年评职称个人工作总结
2015/10/15 职场文书
解决python绘图使用subplots出现标题重叠的问题
2021/04/30 Python
Docker部署Mysql8的实现步骤
2022/07/07 Servers
django项目、vue项目部署云服务器的详细过程
2022/07/23 Servers