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链式调用的实现方法
Mar 07 Javascript
JS操作Cookie写入和读取实例代码
Oct 20 Javascript
Jquery揭秘系列:ajax原生js实现详解(推荐)
Jun 08 Javascript
JS快速实现移动端拼图游戏
Sep 05 Javascript
bootstrap下拉列表与输入框组结合的样式调整
Oct 08 Javascript
微信小程序 教程之wxapp 视图容器 view
Oct 19 Javascript
Bootstrap基本组件学习笔记之按钮组(8)
Dec 07 Javascript
详解JavaScript中的属性和特性
Dec 08 Javascript
简单的渐变轮播插件
Jan 12 Javascript
如何在AngularJs中调用第三方插件库
May 21 Javascript
angularjs实现时间轴效果的示例代码
Nov 29 Javascript
node.js爬取中关村的在线电瓶车信息
Nov 13 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 daddslashes()和 saddslashes()有哪些区别分析
2012/10/26 PHP
php学习笔记之面向对象
2014/11/08 PHP
php在apache环境下实现gzip配置方法
2015/04/02 PHP
php中的单引号、双引号和转义字符详解
2017/02/16 PHP
Yii2.0使用阿里云OSS的SDK上传图片、下载、删除图片示例
2017/09/20 PHP
浅析PHP7的多进程及实例源码
2019/04/14 PHP
php中用unset销毁变量并释放内存
2020/05/10 PHP
能说明你的Javascript技术很烂的五个原因分析
2011/10/28 Javascript
JS仿百度搜索自动提示框匹配查询功能
2013/11/21 Javascript
js字符串截取函数substr substring slice使用对比
2013/11/27 Javascript
JavaScript数组深拷贝和浅拷贝的两种方法
2014/04/16 Javascript
javascript实现图片自动和可控的轮播切换特效
2015/04/13 Javascript
基于jquery实现导航菜单高亮显示(两种方法)
2015/08/23 Javascript
Javascript的无new构建实例详解
2016/05/15 Javascript
js获取当前周、上一周、下一周日期
2017/03/19 Javascript
获取url中用&amp;隔开的参数实例(分享)
2017/05/28 Javascript
angular.js4使用 RxJS 处理多个 Http 请求
2017/09/23 Javascript
微信小程序实现吸顶特效
2020/01/08 Javascript
原生javascript中this几种常见用法总结
2020/02/24 Javascript
JS实现电脑虚拟键盘的操作
2020/06/24 Javascript
python实现中文分词FMM算法实例
2015/07/10 Python
python 中如何获取列表的索引
2019/07/02 Python
kali中python版本的切换方法
2019/07/11 Python
django框架ModelForm组件用法详解
2019/12/11 Python
dpn网络的pytorch实现方式
2020/01/14 Python
Python文本文件的合并操作方法代码实例
2020/03/31 Python
澳洲的UGG雪地靴超级市场:Uggs.com.au
2020/04/06 全球购物
怎样声明子类
2013/07/02 面试题
CAD制图设计师自荐信
2014/01/29 职场文书
对照检查剖析材料
2014/09/30 职场文书
财务部岗位职责范本
2015/04/14 职场文书
总结会主持词
2015/07/02 职场文书
python制作图形界面的2048游戏, 基于tkinter
2021/04/06 Python
Python OpenCV实现传统图片格式与base64转换
2021/06/13 Python
Python编程编写完善的命令行工具
2021/09/15 Python
总结高并发下Nginx性能如何优化
2021/11/01 Servers