详解如何构建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 相关文章推荐
newxtree.js代码
Mar 13 Javascript
在IE6下发生Internet Explorer cannot open the Internet site错误
Jun 21 Javascript
Google Maps API地图应用示例分享
Oct 23 Javascript
JS实现将数字金额转换为大写人民币汉字的方法
Aug 02 Javascript
浅谈JQ中mouseover和mouseenter的区别
Sep 13 Javascript
微信小程序 安全包括(框架、功能模块、账户使用)详解
Jan 16 Javascript
html5+canvas实现支持触屏的签名插件教程
May 08 Javascript
使用Vue的slot插槽分发父组件内容实现高度复用、更加灵活的组件(推荐)
May 01 Javascript
浅谈React的最大亮点之虚拟DOM
May 29 Javascript
ES6基础之 Promise 对象用法实例详解
Aug 22 Javascript
Vue 基于 vuedraggable 实现选中、拖拽、排序效果
May 18 Javascript
如何手写简易的 Vue Router
Oct 10 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合并数组array_merge函数运算符加号与的区别
2008/10/31 PHP
php strnatcmp()函数的用法总结
2013/11/27 PHP
php实现JWT验证的实例教程
2020/11/26 PHP
[原创]来自ImageSee官方 JavaScript图片浏览器
2008/01/16 Javascript
Js日期选择自动填充到输入框(界面漂亮兼容火狐)
2013/08/02 Javascript
扩展IE中一些不兼容的方法如contains、startWith等等
2014/01/09 Javascript
Eclipse去除js(JavaScript)验证错误
2014/02/11 Javascript
JavaScript控制各种浏览器全屏模式的方法、属性和事件介绍
2014/04/03 Javascript
jQuery 跨域访问解决原理案例详解
2016/07/09 Javascript
详解Vue方法与事件
2017/03/09 Javascript
自制简易打赏功能的实例
2017/09/02 Javascript
Vue-cli项目获取本地json文件数据的实例
2018/03/07 Javascript
JS实现倒序输出的几种常用方法示例
2019/04/13 Javascript
[01:10]DOTA2次级职业联赛 - EP战队宣传片
2014/12/01 DOTA
Python调用ctypes使用C函数printf的方法
2017/08/23 Python
python中实现延时回调普通函数示例代码
2017/09/08 Python
Python 异常处理的实例详解
2017/09/11 Python
python实现单向链表详解
2018/02/08 Python
python提取具有某种特定字符串的行数据方法
2018/12/11 Python
JAVA及PYTHON质数计算代码对比解析
2020/06/10 Python
Python如何实现感知器的逻辑电路
2020/12/25 Python
H5 canvas实现贪吃蛇小游戏
2017/07/28 HTML / CSS
HTML5 客户端数据库简易使用:IndexedDB
2019/12/19 HTML / CSS
使用HTML5做的导航条详细步骤
2020/10/19 HTML / CSS
阿迪达斯奥地利官方商城:adidas.at
2016/10/16 全球购物
馥蕾诗美国官网:Fresh美国
2019/10/09 全球购物
PHP两种查询函数array/row的区别
2013/06/03 面试题
小学教育毕业生自荐信
2013/11/18 职场文书
校园报刊亭创业计划书
2014/01/02 职场文书
学术会议邀请函范文
2014/01/22 职场文书
计算机毕业生自荐信范文
2014/03/23 职场文书
高中生家长寄语大全
2014/04/03 职场文书
考博导师推荐信范文
2015/03/27 职场文书
股东大会通知
2015/04/24 职场文书
搞笑婚庆主持词
2015/06/29 职场文书
汉语拼音教学反思
2016/02/22 职场文书