Javascript异步流程控制之串行执行详解


Posted in Javascript onSeptember 27, 2020

这篇文章主要讲一下如何串行执行一组异步任务,例如有下面几个任务,在这里我们用setTimeout模拟一个异步任务:

let taskA = () => setTimeout(() => console.log('run task A'), 100);
let taskB = () => setTimeout(() => console.log('run task B'), 50);
let taskC = () => setTimeout(() => console.log('run task C'), 150);

直接运行

taskA(); taskB(); taskC();

是达不到顺序执行A,B,C 的三个任务的效果的。

首先我们看一下最传统的做法,通过回调的方式在一个任务执行完成之后调用下一个任务:

let taskA = setTimeout(() => {
 console.log('run task A');
 taskB();
}, 100);
let taskB = setTimeout(() => {
 console.log('run task B');
 taskC();
}, 50);
let taskC = setTimeout(() => {
 console.log('run task B');
}, 150);

第二种方法是将每一个任务封装成一个返回Promise的函数, 然后使用使用Promise的链式调用达到串行执行的目的:

let taskA = () => new Promise((resolve, reject) => {
 setTimeout(() => {
  console.log('run task A');
  resolve();
 }, 100);
})
let taskB = () => new Promise((resolve, reject) => {
 setTimeout(() => {
  console.log('run task B');
  resolve();
 }, 50);
})
let taskC = () => new Promise((resolve, reject) => {
 setTimeout(() => {
  console.log('run task C');
  resolve();
 }, 150);
})
function runTasks2() {
  console.log('tasks 2');
  taskA().then(taskB).then(taskC);
}

假设任务的数量不确定,可以通过下面的方式来执行:

function runTasks3(tasks) {
  console.log('tasks 3');
  let pro = tasks[0]();
  for (let i = 1; i < tasks.length; i++) {
  pro.then(tasks[i]);
  }
}

借助于es7的async和await,我们还可以对上面的函数一种写法:

async function runTasks3_1(tasks) {
  for (let i = 0; i < tasks.length; i++) {
  await tasks[i]();
  }
}

在文章的最后我们自己来实现一个串行执行器, 用于执行一组串行任务:

function async(tasks) {
  const count = tasks.length;
  let index = 0;
  const next = () => {
   if (index >= count) return;
   const task = tasks[index++];
   task(next);
  }
  next(0);
}

函数的使用方式如下:

async([
   next => setTimeout(() => { console.log('taskA ...'); next() }, 100),
   next => setTimeout(() => { console.log('taskB ...'); next() }, 50),
   next => setTimeout(() => { console.log('taskC ...'); next() }, 30)
 ]);

在每一个子任务中我们通过调用next函数继续执行下一个子任务。

在具体的使用中可能会遇到函数之间传递参数的情况,即前一个任务的执行结果需要作为下一个任务的入参,这些都可以对上面的例子稍作修改就可以了~~

到此这篇关于Javascript异步流程控制之串行执行详解的文章就介绍到这了,更多相关Javascript串行执行内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Javascript 相关文章推荐
Extjs Ajax 乱码问题解决方案
Apr 15 Javascript
jquery动态加载select下拉框示例代码
Dec 10 Javascript
jQuery实现下拉框左右选择的简单实例
Feb 22 Javascript
JavaScript实现节点的删除与序号重建实例
Aug 05 Javascript
jQuery通过改变input的type属性实现密码显示隐藏切换功能
Feb 08 Javascript
在 Linux/Unix 中不重启 Vim 而重新加载 .vimrc 文件的流程
Mar 21 Javascript
浅谈vue中.vue文件解析流程
Apr 24 Javascript
在vue项目中,将juery设置为全局变量的方法
Sep 25 Javascript
微信小程序实现判断是分享到群还是个人功能示例
May 03 Javascript
vue自定义表单生成器form-create使用详解
Jul 19 Javascript
layui清除radio的选中状态实例
Nov 14 Javascript
vue select 获取value和lable操作
Aug 28 Javascript
vue+elementUI 实现内容区域高度自适应的示例
Sep 26 #Javascript
Openlayers实现测量功能
Sep 25 #Javascript
openlayers4.6.5实现距离量测和面积量测
Sep 25 #Javascript
JQuery Ajax如何实现注册检测用户名
Sep 25 #jQuery
Openlayers测量距离与面积的实现方法
Sep 25 #Javascript
基于JS实现操作成功之后自动跳转页面
Sep 25 #Javascript
OpenLayers3实现测量功能
Sep 25 #Javascript
You might like
DEDE实现转跳属性文档在模板上调用出转跳地址
2016/11/04 PHP
深入理解Yii2.0乐观锁与悲观锁的原理与使用
2017/07/26 PHP
服务端 VBScript 与 JScript 几个相同特性的写法 By shawl.qiu
2007/03/06 Javascript
IE8下String的Trim()方法失效的解决方法
2013/11/08 Javascript
javascript实现des解密加密全过程
2014/04/03 Javascript
NodeJS学习笔记之网络编程
2014/08/03 NodeJs
javascript实现的一个随机点名功能
2014/08/26 Javascript
JS函数定义方式的区别介绍
2016/03/22 Javascript
常用Javascript函数与原型功能收藏(必看篇)
2016/10/09 Javascript
JS拉起或下载app的实现代码
2017/02/22 Javascript
jQuery阻止移动端遮罩层后页面滚动
2017/03/15 Javascript
NodeJs使用Mysql模块实现事务处理实例
2017/05/31 NodeJs
Angularjs之如何在跨域请求中传输Cookie的方法
2018/06/01 Javascript
vue初始化动画加载的实例
2018/09/01 Javascript
js实现移动端轮播图
2020/12/21 Javascript
vue学习之Vue-Router用法实例分析
2020/01/06 Javascript
[02:23]2018DOTA2亚洲邀请赛趣味视频——反应测试
2018/04/04 DOTA
使用 Python 获取 Linux 系统信息的代码
2014/07/13 Python
Python处理JSON时的值报错及编码报错的两则解决实录
2016/06/26 Python
开源Web应用框架Django图文教程
2017/03/09 Python
django反向解析URL和URL命名空间的方法
2018/06/05 Python
Pandas删除数据的几种情况(小结)
2019/06/21 Python
python实现把二维列表变为一维列表的方法分析
2019/10/08 Python
Python数据可视化:箱线图多种库画法
2019/11/06 Python
tensorflow常用函数API介绍
2020/04/19 Python
Python实现加密接口测试方法步骤详解
2020/06/05 Python
pycharm配置QtDesigner的超详细方法
2021/01/25 Python
什么时候需要进行强制类型转换
2016/09/03 面试题
小区门卫岗位职责
2013/12/31 职场文书
幼儿园儿童节主持词
2014/03/21 职场文书
《富饶的西沙群岛》教学反思
2014/04/09 职场文书
交警作风整顿剖析材料
2014/10/11 职场文书
出国留学自荐信模板
2015/03/06 职场文书
小学音乐课歌曲《堆雪人》教学反思
2016/02/18 职场文书
游戏开发中如何使用CocosCreator进行音效处理
2021/04/14 Javascript
为什么mysql字段要使用NOT NULL
2021/05/13 MySQL