详解如何构建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 相关文章推荐
showModelessDialog()使用详解
Sep 07 Javascript
基于KMP算法JavaScript的实现方法分析
May 03 Javascript
javascript中的变量作用域以及变量提升详细介绍
Oct 24 Javascript
html的DOM中document对象anchors集合用法实例
Jan 21 Javascript
js操作css属性实现div层展开关闭效果的方法
May 11 Javascript
简单实现JS倒计时效果
Dec 23 Javascript
jQuery手风琴的简单制作
May 12 jQuery
JS调用安卓手机摄像头扫描二维码
Oct 16 Javascript
vue子路由跳转实现tab选项卡
Jul 24 Javascript
layui 点击重置按钮, select 并没有被重置的解决方法
Sep 03 Javascript
vue中如何实现后台管理系统的权限控制的方法步骤
Sep 05 Javascript
JavaScript异步操作中串行和并行
Nov 20 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实现的三个常用加密解密功能函数示例
2017/11/06 PHP
用Jquery实现可编辑表格并用AJAX提交到服务器修改数据
2009/12/27 Javascript
jquery隐藏标签和显示标签的实例
2013/11/11 Javascript
javascript利用apply和arguments复用方法
2013/11/25 Javascript
推荐 21 款优秀的高性能 Node.js 开发框架
2014/08/18 Javascript
快速学习JavaScript的6个思维技巧
2015/10/13 Javascript
轻松掌握JavaScript享元模式
2016/08/27 Javascript
javascript闭包功能与用法实例分析
2017/04/06 Javascript
bootstrap multiselect 多选功能实现方法
2017/06/05 Javascript
使用Vue构建可重用的分页组件
2018/03/26 Javascript
JavaScript选择排序算法原理与实现方法示例
2018/08/06 Javascript
elementUI Vue 单个按钮显示和隐藏的变换功能(两种方法)
2018/09/04 Javascript
浅谈vue同一页面中拥有两个表单时,的验证问题
2018/09/18 Javascript
vue项目持久化存储数据的实现代码
2018/10/01 Javascript
nodejs基础之buffer缓冲区用法分析
2018/12/26 NodeJs
浅谈python对象数据的读写权限
2016/09/12 Python
对python中的for循环和range内置函数详解
2018/04/17 Python
Python3之读取连接过的网络并定位的方法
2018/04/22 Python
Python HTML解析器BeautifulSoup用法实例详解【爬虫解析器】
2019/04/05 Python
浅谈anaconda python 版本对应关系
2020/10/07 Python
使用HTML5 Canvas API控制字体的显示与渲染的方法
2016/03/24 HTML / CSS
将世界上最美丽的摄影作品转化为艺术作品:Photos.com
2017/11/28 全球购物
Mio Skincare法国官网:身体紧致及孕期身体护理
2018/04/04 全球购物
圣诞树世界:Christmas Tree World
2019/12/10 全球购物
沃尔玛旗下墨西哥超市:Bodega Aurrera
2020/11/13 全球购物
final, finally, finalize的区别
2012/03/01 面试题
市场营销专科应届生求职信
2013/11/24 职场文书
九年级数学教学反思
2014/02/02 职场文书
收银员的岗位职责范本
2014/02/04 职场文书
会计电算化大学生职业规划书
2014/02/05 职场文书
2014年党支部工作总结
2014/11/13 职场文书
2014年保险公司工作总结
2014/11/22 职场文书
医生个人年终总结
2015/02/28 职场文书
《比尾巴》教学反思
2016/02/24 职场文书
CSS 圆形进度栏
2021/04/06 HTML / CSS
MySQL数据库实验之 触发器和存储过程
2022/06/21 MySQL