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一组验证函数
Dec 20 Javascript
六款帮助你实现惊艳视差滚动效果的jQuery插件
Sep 14 Javascript
js中的屏蔽的使用示例
Jul 30 Javascript
Lua表达式和控制结构学习笔记
Dec 15 Javascript
js实现右下角提示框的方法
Feb 03 Javascript
JavaScript设置、获取、清除单值和多值cookie的方法
Nov 17 Javascript
jquery过滤特殊字符',防sql注入的实现方法
Aug 17 Javascript
jQuery实现的简单在线计算器功能
May 11 jQuery
jQuery实现html table行Tr的复制、删除、计算功能
Jul 10 jQuery
vue 自定义提示框(Toast)组件的实现代码
Aug 17 Javascript
jQuery实现简单的Ajax调用功能示例
Feb 15 jQuery
JavaScript 引用类型实例详解【数组、对象、严格模式等】
May 13 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
星际争霸中的热键
2020/03/04 星际争霸
解析:使用php mongodb扩展时 需要注意的事项
2013/06/18 PHP
PHP操作MongoDB GridFS 存储文件的详解
2013/06/20 PHP
SAE实时日志接口SDK用法示例
2016/10/09 PHP
php实现博客,论坛图片防盗链的方法
2016/10/15 PHP
php+ajax实现无刷新文件上传功能(ajaxuploadfile)
2018/02/11 PHP
一个原生的用户等级的进度条
2010/07/03 Javascript
jquery 学习之二 属性(html()与html(val))
2010/11/25 Javascript
jQuery的remove()方法使用详解
2015/08/11 Javascript
理解JS绑定事件
2016/01/19 Javascript
基于JavaScript实现单选框下拉菜单添加文件效果
2016/06/26 Javascript
CSS3 media queries结合jQuery实现响应式导航
2016/09/30 Javascript
jQuery如何防止Ajax重复提交
2016/10/14 Javascript
javaScript基础详解
2017/01/19 Javascript
js轮播图无缝滚动效果
2017/06/17 Javascript
vue 文件目录结构详解
2017/11/24 Javascript
Vue中的无限加载vue-infinite-loading的方法
2018/04/08 Javascript
angular4中*ngFor不能对返回来的对象进行循环的解决方法
2018/09/12 Javascript
vue如何安装使用Quill富文本编辑器
2018/09/21 Javascript
React路由鉴权的实现方法
2019/09/05 Javascript
Python简单连接MongoDB数据库的方法
2016/03/15 Python
Python数据类型详解(三)元祖:tuple
2016/05/08 Python
详解Python装饰器由浅入深
2016/12/09 Python
Python实现曲线拟合操作示例【基于numpy,scipy,matplotlib库】
2018/07/12 Python
django admin 自定义替换change页面模板的方法
2019/08/23 Python
Python shelve模块实现解析
2019/08/28 Python
Django后端分离 使用element-ui文件上传方式
2020/07/12 Python
CSS实现圆形放大镜狙击镜效果 只有圆圈里的放大
2012/12/10 HTML / CSS
用html5实现语音搜索框的方法
2014/03/18 HTML / CSS
HTML5自定义属性前缀data-及dataset的使用方法(html5 新特性)
2017/08/24 HTML / CSS
波兰最大的度假胜地和城市公寓租赁运营商:Sun & Snow
2018/10/18 全球购物
项目施工员岗位职责
2014/03/09 职场文书
彩妆大赛策划方案
2014/05/13 职场文书
区域销售主管岗位职责
2014/06/15 职场文书
Python-OpenCV实现图像缺陷检测的实例
2021/06/11 Python
win10电脑老是死机怎么办?win10系统老是死机的解决方法
2022/08/05 数码科技