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
Jun 05 Javascript
javascript:history.go()和History.back()的区别及应用
Nov 25 Javascript
网页中返回顶部代码(多种方法)另附注释说明
Apr 24 Javascript
基于JavaScript实现本地图片预览
Feb 08 Javascript
jQuery使用bind函数实现绑定多个事件的方法
Oct 11 jQuery
详解如何在项目中使用jest测试react native组件
Feb 09 Javascript
vue中关闭eslint的方法分析
Aug 04 Javascript
深入理解Vue router的部分高级用法
Aug 15 Javascript
javascript中UMD规范的代码推演
Aug 29 Javascript
JS跨域请求的问题解析
Dec 03 Javascript
Vue.js中该如何自己维护路由跳转记录
May 19 Javascript
前端如何实现动画过渡效果
Feb 05 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
使用NetBeans + Xdebug调试PHP程序的方法
2011/04/12 PHP
PHP 观察者模式的实现代码
2013/05/10 PHP
php实现图片添加水印功能
2014/02/13 PHP
PHP内存缓存功能memcached示例
2016/10/19 PHP
jquery图片放大功能简单实现
2013/08/01 Javascript
分享一款基于jQuery的视频播放插件
2014/10/09 Javascript
JS 打印功能代码可实现打印预览、打印设置等
2014/10/31 Javascript
不到30行JS代码实现Excel表格的方法
2014/11/15 Javascript
JavaScript操作class和style样式代码详解
2016/02/13 Javascript
JS模拟简易滚动条效果代码(附demo源码)
2016/04/05 Javascript
JS实现把鼠标放到链接上出现滚动文字的方法
2016/04/06 Javascript
微信小程序 rpx 尺寸单位详细介绍
2016/10/13 Javascript
Vue.js实现简单ToDoList 前期准备(一)
2016/12/01 Javascript
vue mintui-Loadmore结合实现下拉刷新和上拉加载示例
2017/10/12 Javascript
解决vue组件中使用v-for出现告警问题及v for指令介绍
2017/11/11 Javascript
vue-video-player 通过自定义按钮组件实现全屏切换效果【推荐】
2018/08/29 Javascript
vue权限管理系统的实现代码
2019/01/17 Javascript
js中复选框的取值及赋值示例详解
2020/10/18 Javascript
[01:31:02]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第一场
2019/08/22 DOTA
Python中处理字符串之islower()方法的使用简介
2015/05/19 Python
在Python中用keys()方法返回字典键的教程
2015/05/21 Python
详谈Python基础之内置函数和递归
2017/06/21 Python
Python基础学习之常见的内建函数整理
2017/09/06 Python
用不到50行的Python代码构建最小的区块链
2017/11/16 Python
Python学习之用pygal画世界地图实例
2017/12/07 Python
python生成tensorflow输入输出的图像格式的方法
2018/02/12 Python
python实现文本界面网络聊天室
2018/12/12 Python
Python图片的横坐标汉字实例
2019/12/04 Python
css3 伪元素和伪类选择器详解
2014/09/04 HTML / CSS
Stio官网:男女、儿童户外服装
2019/12/13 全球购物
德国富尔达运动鞋店:43einhalb
2020/12/25 全球购物
与UNIX有关的几个名词
2015/09/17 面试题
文化建设工作方案
2014/05/12 职场文书
2015初中政教处工作总结
2015/07/21 职场文书
分析设计模式之模板方法Java实现
2021/06/23 Java/Android
windows server2008 开启端口的实现方法
2022/06/25 Servers