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 相关文章推荐
JQuery中根据属性或属性值获得元素(6种情况获取方法)
Jan 17 Javascript
在js文件中写el表达式取不到值的原因及解决方法
Dec 23 Javascript
iframe父页面获取子页面参数的方法
Feb 21 Javascript
JavaScript控制listbox列表框的项目上下移动的方法
Mar 18 Javascript
Boostrap入门准备之border box
May 09 Javascript
基于layer.js实现收货地址弹框选择然后返回相应的地址信息
May 26 Javascript
vue.js内部自定义指令与全局自定义指令的实现详解(利用directive)
Jul 11 Javascript
详解封装基础的angular4的request请求方法
Jun 05 Javascript
webpack4打包vue前端多页面项目
Sep 17 Javascript
JavaScript RegExp 对象用法详解
Sep 24 Javascript
javascript canvas API内容整理
Feb 16 Javascript
json.stringify()与json.parse()的区别以及用处
Jan 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
c#中的实现php中的preg_replace
2009/12/21 PHP
PHP读取xml方法介绍
2013/01/12 PHP
php使用sql数据库 获取字段问题介绍
2013/08/12 PHP
Laravel框架实现定时Task Scheduling例子
2019/10/22 PHP
textarea的value是html文件源代码,存成html文件的代码
2007/04/20 Javascript
基于jQuery的弹出警告对话框美化插件(警告,确认和提示)
2010/06/10 Javascript
js常用数组操作方法简明总结
2014/06/20 Javascript
alert出数组中的随即值代码
2014/09/25 Javascript
jQuery事件用法详解
2016/10/06 Javascript
AngularJS实现与Java Web服务器交互操作示例【附demo源码下载】
2016/11/02 Javascript
javascript解析ajax返回的xml和json格式数据实例详解
2017/01/05 Javascript
JavaScript之浏览器对象_动力节点Java学院整理
2017/07/03 Javascript
vue-quill-editor富文本编辑器简单使用方法
2018/09/21 Javascript
微信小程序实现展示评分结果功能
2019/02/15 Javascript
Vue结合后台导入导出Excel问题详解
2019/02/19 Javascript
vue实现一拉到底的滑动验证
2019/07/25 Javascript
基于JS实现简单滑块拼图游戏
2019/10/12 Javascript
JavaScript 中的无穷数(Infinity)详解
2020/02/13 Javascript
[52:52]完美世界DOTA2联赛PWL S3 LBZS vs access 第一场 12.10
2020/12/13 DOTA
有关wxpython pyqt内存占用问题分析
2014/06/09 Python
Python3字符串学习教程
2015/08/20 Python
Flask解决跨域的问题示例代码
2018/02/12 Python
pycharm开发一个简单界面和通用mvc模板(操作方法图解)
2020/05/27 Python
英国女性时尚精品店:THE DRESSING ROOM
2018/05/23 全球购物
Raffaello Network西班牙:意大利拉斐尔时尚购物网
2019/03/12 全球购物
Quiksilver美国官网:始于1969年的优质冲浪服和滑雪板外套
2020/04/20 全球购物
Scotch Porter官方网站:男士美容产品
2020/08/31 全球购物
民族精神月活动总结
2014/08/28 职场文书
我与祖国共奋进演讲稿
2014/09/13 职场文书
无刑事犯罪记录证明范本
2014/09/29 职场文书
美国旅游签证工作证明
2014/10/14 职场文书
客房服务员岗位职责
2015/02/09 职场文书
自书遗嘱范文
2015/08/07 职场文书
浅谈如何写好演讲稿?
2019/06/12 职场文书
Go缓冲channel和非缓冲channel的区别说明
2021/04/25 Golang
SQL SERVER存储过程用法详解
2022/02/24 SQL Server