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网页图片按比例自适应缩放实现方法
Jan 15 Javascript
JavaScript中的typeof操作符用法实例
Apr 05 Javascript
JavaScript设计模式经典之工厂模式
Feb 24 Javascript
巧用jQuery选择器提高写表单效率的方法
Aug 19 Javascript
工作中常用的js、jquery自定义扩展函数代码片段汇总
Dec 22 Javascript
手动初始化Angular的模块与控制器
Dec 26 Javascript
JavaScript Canvas绘制圆形时钟效果
Aug 20 Javascript
JavaScript数组_动力节点Java学院整理
Jun 26 Javascript
Express的HTTP重定向到HTTPS的方法
Jun 06 Javascript
解决Vue 项目打包后favicon无法正常显示的问题
Sep 01 Javascript
VUE简单的定时器实时刷新的实现方法
Jan 20 Javascript
关于layui 下拉列表的change事件详解
Sep 20 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: 使用expat函数(二)
2006/10/09 PHP
PHP获取类中常量,属性,及方法列表的方法
2009/04/09 PHP
zend framework中使用memcache的方法
2016/03/04 PHP
微信支付开发动态链接Native支付
2016/07/12 PHP
laravel 5.3中自定义加密服务的方案详解
2017/05/09 PHP
laravel-admin自动生成模块,及相关基础配置方法
2019/10/08 PHP
浅析PHP反序列化中过滤函数使用不当导致的对象注入问题
2020/02/15 PHP
JavaScript与DropDownList 区别分析
2010/01/01 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(四)用地图块拼成大地图
2013/01/23 Javascript
JS控制文本域只读或可写属性的方法
2016/06/24 Javascript
移动端触屏幻灯片图片切换插件idangerous swiper.js
2017/04/10 Javascript
Vuex利用state保存新闻数据实例
2017/06/28 Javascript
vue.js国际化 vue-i18n插件的使用详解
2017/07/07 Javascript
canvas绘制爱心的几种方法总结(推荐)
2017/10/31 Javascript
JavaScript 中使用 Generator的方法
2017/12/29 Javascript
使用 vue.js 构建大型单页应用
2018/02/10 Javascript
Vue 样式绑定的实现方法
2019/01/15 Javascript
JavaScript中的null和undefined用法解析
2019/09/30 Javascript
python实现dnspod自动更新dns解析的方法
2014/02/14 Python
Python线程的两种编程方式
2015/04/14 Python
django.db.utils.ProgrammingError: (1146, u“Table‘’ doesn’t exist”)问题的解决
2018/07/13 Python
django将数组传递给前台模板的方法
2019/08/06 Python
Python操作多维数组输出和矩阵运算示例
2019/11/28 Python
python 通过手机号识别出对应的微信性别(实例代码)
2019/12/22 Python
python如何通过闭包实现计算器的功能
2020/02/22 Python
python GUI库图形界面开发之PyQt5动态(可拖动控件大小)布局控件QSplitter详细使用方法与实例
2020/03/06 Python
python画环形图的方法
2020/03/25 Python
Django 解决distinct无法去除重复数据的问题
2020/05/20 Python
使用pandas库对csv文件进行筛选保存
2020/05/25 Python
python 下载m3u8视频的示例代码
2020/11/11 Python
Sublime Text3最新激活注册码分享适用2020最新版 亲测可用
2020/11/12 Python
美国最大的在线水培用品商店:GrowersHouse.com
2018/08/14 全球购物
《数星星的孩子》教学反思
2014/04/11 职场文书
2019各种承诺书范文
2019/06/24 职场文书
公务员的复习计划书,请收下!
2019/07/15 职场文书
Android开发EditText禁止输入监听及InputFilter字符过滤
2022/06/10 Java/Android