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 DOM学习第四章 getElementByTagNames
Feb 19 Javascript
Fixie.js 自动填充内容的插件
Jun 28 Javascript
JavaScript String.replace函数参数实例说明
Jun 06 Javascript
javascript函数中参数传递问题示例探讨
Jul 31 Javascript
JavaScript实现的GBK、UTF8字符串实际长度计算函数
Aug 27 Javascript
JavaScript组件开发完整示例
Dec 15 Javascript
JavaScript 正则表达式中global模式的特性
Feb 25 Javascript
javascript实现移动端上的触屏拖拽功能
Mar 04 Javascript
JS中setTimeout的巧妙用法前端函数节流
Mar 24 Javascript
javascript history对象详解
Feb 09 Javascript
分分钟学会vue中vuex的应用(入门教程)
Sep 14 Javascript
详解JavaScript中的强制类型转换
Apr 15 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 翻页 实例代码
2009/08/07 PHP
PHP has encountered a Stack overflow问题解决方法
2014/11/03 PHP
PHP获取表单数据与HTML嵌入PHP脚本的实现
2017/02/09 PHP
JavaScript 浮点数运算 精度问题
2009/10/06 Javascript
浅谈Javascript面向对象编程
2011/11/15 Javascript
通过百度地图获取公交线路的站点坐标的js代码
2012/05/11 Javascript
web性能优化之javascript性能调优
2012/12/28 Javascript
jQuery选择器全面总结
2014/01/06 Javascript
JS判断当前页面是否在微信浏览器打开的方法
2015/12/08 Javascript
JavaScript利用HTML DOM进行文档操作的方法
2016/03/28 Javascript
nodejs如何获取时间戳与时间差
2016/08/03 NodeJs
JS匿名函数实例分析
2016/11/26 Javascript
jQuery实现动态添加tr到table的方法
2016/12/26 Javascript
node.js平台下的mysql数据库配置及连接
2017/03/31 Javascript
Bootstrap滚动监听组件scrollspy.js使用方法详解
2017/07/20 Javascript
javascript获取指定区间范围随机数的方法
2017/09/08 Javascript
vue iView 上传组件之手动上传功能
2018/03/16 Javascript
vue渲染时闪烁{{}}的问题及解决方法
2018/03/28 Javascript
微信小程序仿RadioGroup改变样式的处理方案
2018/07/13 Javascript
微信小程序使用setData修改数组中单个对象的方法分析
2018/12/30 Javascript
浅谈Javascript中的对象和继承
2019/04/19 Javascript
vue输入框使用模糊搜索功能的实现代码
2020/05/26 Javascript
手动实现把python项目发布为exe可执行程序过程分享
2014/10/23 Python
Python管理Windows服务小脚本
2018/03/12 Python
python ddt实现数据驱动
2018/03/14 Python
python3+PyQt5自定义视图详解
2018/04/24 Python
linux下python使用sendmail发送邮件
2018/05/22 Python
Python通过递归函数输出嵌套列表元素
2020/10/15 Python
详解移动端HTML5音频与视频问题及解决方案
2018/08/22 HTML / CSS
canvas离屏技术与放大镜实现代码示例
2018/08/31 HTML / CSS
美国汽配连锁巨头Pep Boys官网:轮胎更换、汽车维修服务和汽车零部件
2017/01/14 全球购物
linux面试题参考答案(6)
2016/06/23 面试题
电大自我鉴定范文
2013/10/01 职场文书
气象学专业个人求职信
2014/03/15 职场文书
私人委托书格式
2014/09/10 职场文书
2014年销售员工作总结
2014/12/01 职场文书