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 相关文章推荐
javascript中的对象和数组的应用技巧
Jan 07 Javascript
javascript 播放器 控制
Jan 22 Javascript
JavaScript 常用函数库详解
Oct 21 Javascript
从数据库读取数据后将其输出成html标签的三种方法
Oct 13 Javascript
用svg制作富有动态的tooltip
Jul 17 Javascript
JavaScript的Polymer框架中dom-repeat与VM的相关操作
Jul 29 Javascript
js实现StringBuffer的简单实例
Sep 02 Javascript
详解easyui基于 layui.laydate日期扩展组件
Jul 18 Javascript
解决微信小程序防止无法回到主页的问题
Sep 28 Javascript
JQuery搜索框自动补全(模糊匹配)功能实现示例
Jan 08 jQuery
Vue实现简单的拖拽效果
Aug 25 Javascript
vue 判断页面是首次进入还是再次刷新的实例
Nov 05 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
PHP Memcached + APC + 文件缓存封装实现代码
2010/03/11 PHP
php cache类代码(php数据缓存类)
2010/04/15 PHP
整理的一些实用WordPress后台MySQL操作命令
2013/01/07 PHP
ThinkPHP后台首页index使用frameset时的注意事项分析
2014/08/22 PHP
Yii统计不同类型邮箱数量的方法
2016/10/18 PHP
带左右箭头图片轮播的JS代码
2013/12/18 Javascript
jquery自动填充勾选框即把勾选框打上true
2014/03/24 Javascript
jquery禁用右键示例
2014/04/28 Javascript
详谈javascript中DOM的基本属性
2015/02/26 Javascript
JavaScript实现页面5秒后自动跳转的方法
2015/04/16 Javascript
jquery SweetAlert插件实现响应式提示框
2015/08/18 Javascript
javascript实现tab切换的两个实例
2015/11/05 Javascript
Js实现简单的小球运动特效
2016/02/18 Javascript
微信小程序 获取设备信息 API实例详解
2016/10/02 Javascript
微信小程序教程系列之视图层的条件渲染(10)
2017/04/19 Javascript
Vue2.0父组件与子组件之间的事件发射与接收实例代码
2017/09/19 Javascript
解决在vue+webpack开发中出现两个或多个菜单公用一个组件问题
2017/11/28 Javascript
移动端如何用下拉刷新的方式实现上拉加载
2018/12/10 Javascript
微信小游戏之使用three.js 绘制一个旋转的三角形
2019/06/10 Javascript
JS实现图片切换特效
2019/12/23 Javascript
python使用tkinter实现简单计算器
2018/01/30 Python
NumPy统计函数的实现方法
2020/01/21 Python
Python numpy矩阵处理运算工具用法汇总
2020/07/13 Python
html5 Canvas画图教程(9)—canvas中画出矩形和圆形
2013/01/09 HTML / CSS
HTML5 实现图片上传预处理功能
2020/02/06 HTML / CSS
香港卓悦化妆品官网:BONJOUR
2017/09/21 全球购物
英国团购网站:Groupon英国
2017/11/28 全球购物
世界上最大的高分辨率在线图片库:Alamy
2018/07/07 全球购物
新东网科技Java笔试题
2012/07/13 面试题
出纳员岗位职责
2014/03/13 职场文书
催款律师函范文
2015/05/27 职场文书
银行安全保卫工作总结
2015/08/10 职场文书
维护民族团结心得体会2016
2016/01/15 职场文书
2016年庆祝六一儿童节活动总结
2016/04/06 职场文书
Springboot如何使用logback实现多环境配置?
2021/06/16 Java/Android
Python 处理表格进行成绩排序的操作代码
2021/07/26 Python