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函数
Aug 01 Javascript
验证码在IE中不刷新而谷歌等浏览器正常的解决方案
Mar 18 Javascript
基于d3.js实现实时刷新的折线图
Aug 03 Javascript
jQuery为动态生成的select元素添加事件的方法
Aug 29 Javascript
js实现鼠标左右移动,图片也跟着移动效果
Jan 25 Javascript
React组件之间的通信的实例代码
Jun 27 Javascript
详解给Vue2路由导航钩子和axios拦截器做个封装
Apr 10 Javascript
浅谈Vue响应式(数组变异方法)
May 07 Javascript
深入理解JavaScript的值传递和引用传递
Oct 24 Javascript
微信公众平台 发送模板消息(Java接口开发)
Apr 17 Javascript
JS实现的定时器展示简单秒表、页面弹框及跳转操作完整示例
Jan 26 Javascript
解决vant中 tab栏遇到的坑 van-tabs
Nov 04 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
C# Assembly类访问程序集信息
2009/06/13 PHP
PHP错误Warning:mysql_query()解决方法
2015/10/24 PHP
Laravel中Facade的加载过程与原理详解
2017/09/22 PHP
PHPCrawl爬虫库实现抓取酷狗歌单的方法示例
2017/12/21 PHP
tp5框架前台无限极导航菜单类实现方法分析
2020/03/29 PHP
用JavaScript脚本实现Web页面信息交互
2006/10/11 Javascript
用Javscript实现表单复选框的全选功能
2007/05/25 Javascript
利用谷歌地图API获取点与点的距离的js代码
2012/10/11 Javascript
jquery DIV撑大让滚动条滚到最底部代码
2013/06/06 Javascript
判断一个对象是否为jquery对象的方法
2014/03/12 Javascript
jquery插件hiAlert实现网页对话框美化
2015/05/03 Javascript
js实现异步循环实现代码
2016/02/16 Javascript
JavaScript实现的CRC32函数示例
2016/11/23 Javascript
简单实现Vue的observer和watcher
2016/12/21 Javascript
JavaScript数据结构之广义表的定义与表示方法详解
2017/04/12 Javascript
JS引用传递与值传递的区别与用法分析
2018/06/01 Javascript
纯js实现无缝滚动功能代码实例
2020/02/21 Javascript
Python ORM框架SQLAlchemy学习笔记之关系映射实例
2014/06/10 Python
Python判断操作系统类型代码分享
2014/11/22 Python
详解python3百度指数抓取实例
2016/12/12 Python
python用reduce和map把字符串转为数字的方法
2016/12/19 Python
Django压缩静态文件的实现方法详析
2018/08/26 Python
Centos部署django服务nginx+uwsgi的方法
2019/01/02 Python
使用django和vue进行数据交互的方法步骤
2019/11/11 Python
使用Django xadmin 实现修改时间选择器为不可输入状态
2020/03/30 Python
python 解决selenium 中的 .clear()方法失效问题
2020/09/01 Python
德国网上宠物店:Zoobio
2018/05/23 全球购物
英国IT硬件供应商,定制游戏PC:Mesh Computers
2019/03/28 全球购物
万年牢教学反思
2014/02/15 职场文书
安全生产实施方案
2014/02/23 职场文书
文秘大学生求职信
2014/02/25 职场文书
乔丹名人堂演讲稿
2014/05/24 职场文书
2015年毕业生自我鉴定模板
2014/09/19 职场文书
企业承诺书格式范文
2015/04/28 职场文书
MySQL命令行操作时的编码问题详解
2021/04/14 MySQL
Mysql数据库命令大全
2021/05/26 MySQL