详解如何构建Promise队列实现异步函数顺序执行


Posted in Javascript onOctober 23, 2018

场景

有a、b、c三个异步任务,要求必须先执行a,再执行b,最后执行c

且下一次任务必须要拿到上一次任务执行的结果,才能做操作

思路

我们需要实现一个队列,将这些异步函数添加进队列并且管理它们的执行,队列具有First In First Out的特性,也就是先添加进去的会被先执行,接着才会执行下一个(注意跟栈作区别)

大家也可以类比一下jQuery的animate方法,添加多个动画也会按顺序执行

解决

模拟3个异步函数

// 异步函数a
var a = function () {
 return new Promise(function (resolve, reject) {
  setTimeout(function () {
   resolve('a')
  }, 1000)
 })
}

// 异步函数b
var b = function (data) {
 return new Promise(function (resolve, reject) {
  resolve(data + 'b')
 })
}

// 异步函数c
var c = function (data) {
 return new Promise(function (resolve, reject) {
  setTimeout(function () {
   resolve(data + 'c')
  }, 500)
 })
}

解决方法一(使用then链式操作)

特点:可以满足需求,但是书写比较繁琐

代码

//链式调用
a()
 .then(function (data) {
  return b(data)
 })
 .then(function (data) {
  return c(data)
 })
 .then(function (data) {
  console.log(data)// abc
 })

方法二(构建队列)

特点:封装方法,可移植到别处使用

代码

// 构建队列
function queue(arr) {
 var sequence = Promise.resolve()
 arr.forEach(function (item) {
  sequence = sequence.then(item)
 })
 return sequence
}

// 执行队列
queue([a, b, c])
 .then(data => {
  console.log(data)// abc
 })

方法三(使用async、await构建队列)

同方法二,只是显得更高大上点

代码

async function queue(arr) {
 let res = null
 for (let promise of arr) {
  res = await promise(res)
 }
 return await res
}
queue([a, b, c])
 .then(data => {
  console.log(data)// abc
 })

顺便说一句,bluebird的Promise.reduce也可以用来顺序执行函数,但是可使用的场景非常有限,一般用来读取文件信息,而以上给出的方法,不管你在异步函数中做了什么,只要函数最后返回了一个Promise对象,都可以使用

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
复制小说文本时出现的随机乱码的去除方法
Sep 07 Javascript
基于Jquery实现表格动态分页实现代码
Jun 21 Javascript
imgAreaSelect 中文文档帮助说明
Oct 08 Javascript
js 数组去重的四种实用方法
Sep 09 Javascript
jQuery自定义滚动条完整实例
Jan 08 Javascript
php基于redis处理session的方法
Mar 14 Javascript
JQuery的Pager分页器实现代码
May 03 Javascript
基于jQuery的select下拉框选择触发事件实例分析
Nov 18 Javascript
微信小程序访问node.js接口服务器搭建教程
Apr 25 Javascript
微信小程序如何获知用户运行小程序的场景教程
May 17 Javascript
详解封装基础的angular4的request请求方法
Jun 05 Javascript
JavaScript JSON数据处理全集(小结)
Aug 15 Javascript
jquery实现动态添加附件功能
Oct 23 #jQuery
Vue创建头部组件示例代码详解
Oct 23 #Javascript
JavaScript 对引擎、运行时、调用堆栈的概述理解
Oct 22 #Javascript
每个 JavaScript 工程师都应懂的33个概念
Oct 22 #Javascript
jQuery.validate.js表单验证插件的使用代码详解
Oct 22 #jQuery
React SSR样式及SEO的实践
Oct 22 #Javascript
微信开发之微信jssdk录音功能开发示例
Oct 22 #Javascript
You might like
php生成酷炫的四个字符验证码
2016/04/22 PHP
thinkPHP框架实现图像裁剪、缩放、加水印的方法
2017/03/14 PHP
Laravel第三方包报class not found的解决方法
2019/10/13 PHP
基于jQuery的弹出框插件
2012/03/18 Javascript
JavaScript实现控制打开文件另存为对话框的方法
2015/04/17 Javascript
javascript图片预加载实例分析
2015/07/16 Javascript
javascript中caller和callee详解
2015/08/10 Javascript
jQuery实现的简单分页示例
2016/06/01 Javascript
使用Vue自定义指令实现Select组件
2018/05/24 Javascript
利用Node.js如何实现文件循环覆写
2019/04/05 Javascript
[04:09]2018年度DOTA2社区贡献奖-完美盛典
2018/12/16 DOTA
[59:42]Secret vs Alliacne 2019国际邀请赛小组赛 BO2 第一场 8.15
2019/08/17 DOTA
Python中pip安装非PyPI官网第三方库的方法
2015/06/02 Python
Python实现获取邮箱内容并解析的方法示例
2018/06/16 Python
分析python请求数据
2018/08/19 Python
为什么Python中没有"a++"这种写法
2018/11/27 Python
python 运用Django 开发后台接口的实例
2018/12/11 Python
Python实现二维曲线拟合的方法
2018/12/29 Python
python简单鼠标自动点击某区域的实例
2019/06/25 Python
python中用logging实现日志滚动和过期日志删除功能
2019/08/20 Python
Python之Numpy的超实用基础详细教程
2019/10/23 Python
Python 3.8 新功能来一波(大部分人都不知道)
2020/03/11 Python
python实现简单俄罗斯方块
2020/03/13 Python
python批量修改文件名的示例
2020/09/27 Python
简单掌握CSS3将文字描边及填充文字颜色的方法
2016/03/07 HTML / CSS
HTML5 canvas基本绘图之填充样式实现
2016/06/27 HTML / CSS
微观物理专业自荐信
2014/01/26 职场文书
个人委托书范本
2014/04/02 职场文书
镇党政领导班子民主生活会思想汇报
2014/10/11 职场文书
优秀教师个人材料
2014/12/15 职场文书
教师节主持词开场白
2015/05/29 职场文书
三八节活动主持词
2015/07/04 职场文书
2016年基层党支部书记公开承诺书
2016/03/25 职场文书
2016年“12.3”国际残疾人日活动总结
2016/04/01 职场文书
python 利用 PIL 将数组值转成图片的实现
2021/04/12 Python
【DOTA2】半决赛强强对话~ PSG LGD vs EHOME - DPC 2022 CN REGIONAL FINALS WINTER
2022/04/02 DOTA