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 引发两次$(document.ready)事件
Jan 15 Javascript
用jquery实现的一个超级简单的下拉菜单
May 18 Javascript
jQuery解析json数据实例分析
Nov 24 Javascript
动态加载JavaScript文件的两种方法
Apr 22 Javascript
Ext JS框架程序中阻止键盘触发回退或者刷新页面的代码分享
Jun 07 Javascript
第一次接触神奇的Bootstrap
Oct 14 Javascript
如何制作幻灯片(代码分享)
Jan 06 Javascript
JavaScript和jQuery制作光棒效果
Feb 24 Javascript
vue-cli2.9.3 详细教程
Apr 23 Javascript
Vue中的methods、watch、computed的区别
Nov 26 Javascript
一文了解vue-router之hash模式和history模式
May 31 Javascript
原生js无缝轮播插件使用详解
Mar 09 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 curl_setopt 函数的相关应用及介绍
2013/06/17 PHP
PHP命名空间(namespace)的使用基础及示例
2014/08/18 PHP
php实现QQ空间获取当前用户的用户名并生成图片
2015/07/25 PHP
yii2带搜索功能的下拉框实例详解
2016/05/12 PHP
Yii框架参数配置文件params用法实例分析
2019/09/11 PHP
laravel框架邮箱认证实现方法详解
2019/11/22 PHP
PHP程序员简单的开展服务治理架构操作详解(三)
2020/05/14 PHP
Javascript 八进制转义字符(8进制)
2011/04/08 Javascript
jquery实现textarea 高度自适应
2015/03/11 Javascript
jquery图片切换实例分析
2015/04/15 Javascript
JS选中checkbox后获取table内一行TD所有数据的方法
2015/07/01 Javascript
JavaScript实现简单精致的图片左右无缝滚动效果
2017/03/16 Javascript
bootstrap3使用bootstrap datetimepicker日期插件
2017/05/24 Javascript
jquery实现左右轮播图效果
2017/09/28 jQuery
jQuery NProgress.js加载进度插件的简单使用方法
2018/01/31 jQuery
原生JS实现的多个彩色小球跟随鼠标移动动画效果示例
2018/02/01 Javascript
使用vue + less 实现简单换肤功能的示例
2018/02/21 Javascript
微信公众号H5支付接口调用方法
2019/01/10 Javascript
vue插件mescroll.js实现移动端上拉加载和下拉刷新
2019/03/07 Javascript
JS实现随机抽选获奖者
2019/11/07 Javascript
node.js中 redis 的安装和基本操作示例
2020/02/10 Javascript
微信小程序scroll-view的滚动条设置实现
2020/03/02 Javascript
[33:33]完美世界DOTA2联赛PWL S2 FTD.C vs SZ 第二场 11.27
2020/11/30 DOTA
python操作数据库之sqlite3打开数据库、删除、修改示例
2014/03/13 Python
Python/ArcPy遍历指定目录中的MDB文件方法
2018/10/27 Python
python 获取utc时间转化为本地时间的方法
2018/12/31 Python
PyQt打开保存对话框的方法和使用详解
2019/02/27 Python
python错误调试及单元文档测试过程解析
2019/12/19 Python
QT5 Designer 打不开的问题及解决方法
2020/08/20 Python
法国一家芭蕾舞鞋公司:Repetto
2018/11/12 全球购物
Otticanet美国:最顶尖的世界名牌眼镜, 能得到打折季的价格
2019/03/10 全球购物
Python如何实现单例模式
2016/06/03 面试题
怎样写好自我鉴定
2013/12/04 职场文书
行政人事专员岗位职责
2015/04/07 职场文书
婚礼伴郎致辞
2015/07/28 职场文书
javascript条件式访问属性和箭头函数介绍
2021/11/17 Javascript