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 相关文章推荐
Prototype PeriodicalExecuter对象 学习
Jul 19 Javascript
javascript 自定义事件初探
Aug 21 Javascript
ajax 缓存 问题 requestheader
Aug 01 Javascript
JS中的substring和substr函数的区别说明
May 07 Javascript
关闭页面window.location事件未执行的原因及解决方法
Sep 01 Javascript
JS扩展方法实例分析
Apr 15 Javascript
java必学必会之static关键字
Dec 03 Javascript
JavaScript中Promise的使用详解
Feb 26 Javascript
vue中各组件之间传递数据的方法示例
Jul 27 Javascript
简单实现jQuery轮播效果
Aug 18 jQuery
angular5 httpclient的示例实战
Mar 12 Javascript
ES6模板字符串和标签模板的应用实例分析
Jun 25 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中使用addslashes函数报错问题的解决方法
2013/02/06 PHP
深入解析PHP 5.3.x 的strtotime() 时区设定 警告信息修复
2013/08/05 PHP
php实现的DateDiff和DateAdd时间函数代码分享
2014/08/16 PHP
php实现refresh刷新页面批量导入数据的方法
2014/12/23 PHP
php 实现一个字符串加密解密的函数实例代码
2016/11/01 PHP
php使用高斯算法实现图片的模糊处理功能示例
2016/11/11 PHP
IE下使用cloneNode注意事项分享
2012/11/22 Javascript
JS文本框默认值处理详解
2013/07/10 Javascript
jquery实现网页查找功能示例分享
2014/02/12 Javascript
一个简单的Node.js异步操作管理器分享
2014/04/29 Javascript
javascript编程异常处理实例小结
2015/11/30 Javascript
JavaScript function函数种类详解
2016/02/22 Javascript
基于BootStrap Metronic开发框架经验小结【三】下拉列表Select2插件的使用
2016/05/12 Javascript
JS组件Bootstrap Table使用实例分享
2016/05/30 Javascript
JavaScript代码实现图片循环滚动效果
2020/03/19 Javascript
Angular2使用Guard和Resolve进行验证和权限控制
2017/04/24 Javascript
Vue.2.0.5实现Class 与 Style 绑定的实例
2017/06/20 Javascript
原生js实现随机点名功能
2019/11/05 Javascript
[02:05]2014DOTA2西雅图邀请赛 老队长全明星大猜想谁不服就按进显示器
2014/07/08 DOTA
[01:06]DOTA2小知识课堂 Ep.02 吹风竟可解梦境缠绕
2019/12/05 DOTA
python打开使用的方法
2019/09/30 Python
Python函数式编程指南:对生成器全面讲解
2019/11/19 Python
基于CentOS搭建Python Django环境过程解析
2020/08/24 Python
python实现图片素描效果
2020/09/26 Python
美国娱乐和流行文化商品店:FYE
2017/09/14 全球购物
将"引用"作为函数参数有哪些特点
2013/04/05 面试题
一道Delphi上机题
2012/06/04 面试题
幼儿园实习自我鉴定
2013/12/15 职场文书
安全生产先进个人材料
2014/02/06 职场文书
2014老师三严三实对照检查材料思想汇报
2014/09/18 职场文书
党组织领导班子整改方案
2014/10/25 职场文书
给女朋友道歉的话大全
2015/01/20 职场文书
中班下学期个人总结
2015/02/12 职场文书
redis调用二维码时的不断刷新排查分析
2022/04/01 Redis
Python用any()函数检查字符串中的字母以及如何使用all()函数
2022/04/14 Python
什么是css原子化,有什么用?
2022/04/24 HTML / CSS