详解如何构建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 相关文章推荐
jQuery 剧场版 你必须知道的javascript
May 27 Javascript
新鲜出炉的js tips提示效果
Apr 03 Javascript
Javascript call和apply区别及使用方法
Nov 14 Javascript
验证控件与Button的OnClientClick事件详细解析
Dec 04 Javascript
jquery.ajax的url中传递中文乱码问题的解决方法
Feb 07 Javascript
JQuery工具函数汇总
Jun 15 Javascript
JS实现来回出现文字的状态栏特效代码
Oct 31 Javascript
canvas实现图像放大镜
Feb 06 Javascript
javascript设计模式之单体模式学习笔记
Feb 15 Javascript
js鼠标移动时禁止选中文字
Feb 19 Javascript
如何在微信小程序中实现Mixins方案
Jun 20 Javascript
Angular进行简单单元测试的实现方法实例
Aug 16 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中防止SQL注入攻击和XSS攻击的两个简单方法
2010/04/15 PHP
php中__destruct与register_shutdown_function执行的先后顺序问题
2014/10/17 PHP
PHP使用NuSOAP调用Web服务的方法
2015/07/18 PHP
万能的php分页类
2017/07/06 PHP
PHP验证类的封装与使用方法详解
2019/01/10 PHP
PHP isset empty函数相关面试题及解析
2020/12/11 PHP
jQuery图片预加载 等比缩放实现代码
2011/10/04 Javascript
jcrop基本参数一览
2013/07/16 Javascript
深入理解javascript中的立即执行函数(function(){…})()
2014/06/12 Javascript
jquery插件Jplayer使用方法简析
2016/04/22 Javascript
浅析jquery如何判断滚动条滚到页面底部并执行事件
2016/04/29 Javascript
js实现动态创建的元素绑定事件
2016/07/19 Javascript
onmouseover事件和onmouseout事件全面理解
2016/08/15 Javascript
vue-cli实现多页面多路由的示例代码
2018/01/30 Javascript
浅谈super-vuex使用体验
2018/06/25 Javascript
vue封装一个简单的div框选时间的组件的方法
2019/01/06 Javascript
JQuery animate动画应用示例
2019/05/14 jQuery
解决vue cli使用typescript后打包巨慢的问题
2019/09/30 Javascript
Vue实现push数组并删除的例子
2019/11/01 Javascript
原理深度解析Vue的响应式更新比React快
2020/04/04 Javascript
jQuery实现tab栏切换效果
2020/12/22 jQuery
Python制作爬虫抓取美女图
2016/01/20 Python
python多进程实现进程间通信实例
2017/11/24 Python
在windows下Python打印彩色字体的方法
2018/05/15 Python
浅谈DataFrame和SparkSql取值误区
2018/06/09 Python
Python设计模式之简单工厂模式实例详解
2019/01/22 Python
Python绘制堆叠柱状图的实例
2019/07/09 Python
如何基于python操作excel并获取内容
2019/12/24 Python
Python requests模块安装及使用教程图解
2020/06/30 Python
python中round函数保留两位小数的方法
2020/12/04 Python
骨干教师培训制度
2014/01/13 职场文书
模具专业毕业生自荐书范文
2014/02/19 职场文书
班主任寄语大全
2014/04/04 职场文书
战略合作意向书
2014/07/29 职场文书
践行党的群众路线心得体会
2014/11/05 职场文书
Tomcat项目启动失败的原因和解决办法
2022/04/20 Servers