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 相关文章推荐
ASP.NET jQuery 实例18 通过使用jQuery validation插件校验DropDownList
Feb 03 Javascript
json原理分析及实例介绍
Nov 29 Javascript
jQuery中(function(){})()执行顺序的理解
Mar 05 Javascript
js 剪切板的用法(clipboardData.setData)与js match函数介绍
Nov 19 Javascript
iframe跨域通信封装详解
Aug 11 Javascript
探讨AngularJs中ui.route的简单应用
Nov 16 Javascript
纯js实现倒计时功能
Jan 06 Javascript
微信小程序 登陆流程详细介绍
Jan 17 Javascript
详解layui弹窗父子窗口之间传参数的方法
Jan 16 Javascript
jQuery实现碰到边缘反弹的动画效果
Feb 24 jQuery
浅谈Angular 的变化检测的方法
Mar 01 Javascript
Element中的Cascader(级联列表)动态加载省\市\区数据的方法
Mar 27 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实现动态web服务器方法
2015/07/29 PHP
PHP实现用户登录的案例代码
2018/05/10 PHP
thinkPHP框架通过Redis实现增删改查操作的方法详解
2019/05/13 PHP
event.srcElement 用法笔记e.target
2009/12/18 Javascript
国外大牛IE版本检测!现在IE都到9了,IE检测代码
2012/01/04 Javascript
jQuery Ajax()方法使用指南
2014/11/19 Javascript
javascript解三阶幻方(九宫格)
2015/04/22 Javascript
jQuery插件jRumble实现网页元素抖动
2015/06/05 Javascript
JS结合bootstrap实现基本的增删改查功能
2016/07/22 Javascript
微信小程序 wxapp地图 map详解
2016/10/31 Javascript
浅谈javascript中执行环境(作用域)与作用域链
2016/12/08 Javascript
12 款 JS 代码测试必备工具(翻译)
2016/12/13 Javascript
简单实现IONIC购物车功能
2017/01/10 Javascript
nodejs制作爬虫实现批量下载图片
2017/05/19 NodeJs
JS 组件系列之BootstrapTable的treegrid功能
2017/06/16 Javascript
浅谈react 同构之样式直出
2017/11/07 Javascript
vue集成百度UEditor富文本编辑器使用教程
2018/09/21 Javascript
详解vue引入子组件方法
2019/02/12 Javascript
详解从vue-loader源码分析CSS Scoped的实现
2019/09/23 Javascript
微信jssdk踩坑之签名错误invalid signature
2020/05/19 Javascript
Python中的urllib模块使用详解
2015/07/07 Python
Python利用前序和中序遍历结果重建二叉树的方法
2016/04/27 Python
Python基于csv模块实现读取与写入csv数据的方法
2018/01/18 Python
Python中Proxypool库的安装与配置
2018/10/19 Python
使用浏览器访问python写的服务器程序
2019/10/10 Python
python如何控制进程或者线程的个数
2020/10/16 Python
Lulu Guinness露露·吉尼斯官网:红唇包
2019/02/03 全球购物
正风肃纪剖析材料
2014/02/18 职场文书
企业道德讲堂实施方案
2014/03/19 职场文书
经典安踏广告词
2014/03/21 职场文书
新年联欢会主持词
2014/03/27 职场文书
大四学生找工作的自荐信
2014/03/27 职场文书
关于青春的演讲稿800字
2014/08/22 职场文书
个人自荐书怎么写
2015/03/26 职场文书
孙振耀退休感言
2015/08/01 职场文书
Java 多线程并发FutureTask
2022/06/28 Java/Android