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 相关文章推荐
js自执行函数的几种不同写法的比较
Aug 16 Javascript
jquery连缀语法如何实现
Nov 29 Javascript
JS将滑动门改为选项卡(需鼠标点击)的实现方法
Sep 27 Javascript
跟我学习javascript的循环
Nov 18 Javascript
学习jQuey中的return false
Dec 18 Javascript
js+css实现回到顶部按钮(back to top)
Mar 02 Javascript
jQuery常用的一些技巧汇总
Mar 26 Javascript
vue-cli如何添加less 以及sass
Jul 06 Javascript
Vue2.0中三种常用传值方式(父传子、子传父、非父子组件传值)
Aug 16 Javascript
vue实现条件叠加搜索的解决方法
May 28 Javascript
js tab栏切换代码实例解析
Sep 03 Javascript
vue实现页面内容禁止选中功能,仅输入框和文本域可选
Nov 09 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文件上传(实例)
2013/10/27 PHP
php目录操作实例代码
2014/02/21 PHP
PHP中Http协议post请求参数
2015/11/02 PHP
Zend Framework动作助手Redirector用法实例详解
2016/03/05 PHP
php compact 通过变量创建数组
2016/11/15 PHP
php微信开发之谷歌测距
2018/06/14 PHP
jQuery实现在textarea指定位置插入字符或表情的方法
2015/03/11 Javascript
解决jquery实现的radio重新选中的问题
2015/07/03 Javascript
聊一聊JavaScript作用域和作用域链
2016/05/03 Javascript
后端接收不到AngularJs中$http.post发送的数据原因分析及解决办法
2016/07/05 Javascript
Vuex2.0+Vue2.0构建备忘录应用实践
2016/11/30 Javascript
Bootstrap基本组件学习笔记之分页(12)
2016/12/08 Javascript
javascript checkbox/radio onchange不能兼容ie8处理办法
2017/06/13 Javascript
jQuery实现通过方向键控制div块上下左右移动的方法【测试可用】
2018/04/26 jQuery
浅谈node.js 命令行工具(cli)
2018/05/10 Javascript
NodeJS实现同步的方法
2019/03/02 NodeJs
了解JavaScript函数中的默认参数
2019/05/30 Javascript
React倒计时功能实现代码——解耦通用
2020/09/18 Javascript
Python之str操作方法(详解)
2017/06/19 Python
python制作小说爬虫实录
2017/08/14 Python
python版微信跳一跳游戏辅助
2018/01/11 Python
numpy给array增加维度np.newaxis的实例
2018/11/01 Python
Numpy一维线性插值函数的用法
2020/04/22 Python
浅谈Python描述数据结构之KMP篇
2020/09/06 Python
全网最全python库selenium自动化使用详细教程
2021/01/12 Python
html5文字阴影效果text-shadow使用示例
2013/07/25 HTML / CSS
HTML5+WebSocket实现多文件同时上传的实例
2016/12/29 HTML / CSS
英国排名第一的礼品体验公司:Red Letter Days
2018/08/16 全球购物
护士自我鉴定
2013/10/23 职场文书
如何填写个人简历自我评价
2013/12/10 职场文书
音乐教学随笔感言
2014/02/19 职场文书
俄语专业职业生涯规划
2014/02/26 职场文书
我的求职择业计划书
2014/04/04 职场文书
煤矿安全生产责任书
2014/04/15 职场文书
考生诚信考试承诺书
2015/04/29 职场文书
matplotlib如何设置坐标轴刻度的个数及标签的方法总结
2021/06/11 Python