详解如何构建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 相关文章推荐
JavaScript(JS) 压缩 / 混淆 / 格式化 批处理工具
Dec 10 Javascript
基于jquery实现的移入页面上空文本框时,让它变为焦点,移出清除焦点
Jul 26 Javascript
js+css实现增加表单可用性之提示文字
Jun 03 Javascript
JavaScript阻止事件冒泡示例分享
Dec 28 Javascript
js实现刷新iframe的方法汇总
Apr 27 Javascript
基于JS实现EOS隐藏错误提示层代码
Apr 25 Javascript
微信小程序 swiper组件详解及实例代码
Oct 25 Javascript
js+html5实现侧滑页面效果
Jul 15 Javascript
JavaScript学习笔记之基于定时器实现图片无缝滚动功能详解
Jan 09 Javascript
JavaScript中AOP的实现与应用
May 06 Javascript
原生javascript运动函数的封装示例【匀速、抛物线、多属性的运动等】
Feb 23 Javascript
Vue axios与Go Frame后端框架的Options请求跨域问题详解
Mar 03 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
检测png图片是否完整的php代码
2010/09/06 PHP
php字符串截取函数用法分析
2014/11/25 PHP
php调整服务器时间的方法
2015/04/03 PHP
php表单文件iframe异步上传实例讲解
2017/07/26 PHP
PHP实现的Redis多库选择功能单例类
2017/07/27 PHP
php app支付宝回调(异步通知)详解
2018/07/25 PHP
PhpStorm的使用教程(本地运行PHP+远程开发+快捷键)
2020/03/26 PHP
jQuery插件 tabBox实现代码
2010/02/09 Javascript
JavaScript自动设置IFrame高度的小例子
2013/06/08 Javascript
JavaScript版TAB选项卡效果实例
2013/08/16 Javascript
JQuery包裹DOM节点的方法
2015/06/11 Javascript
textarea 在浏览器中固定大小和禁止拖动的实现方法
2016/12/03 Javascript
JavaScript之创意时钟项目(实例讲解)
2017/10/23 Javascript
AngularJS双向数据绑定原理之$watch、$apply和$digest的应用
2018/01/30 Javascript
vue中axios防止多次触发终止多次请求的示例代码(防抖)
2020/02/16 Javascript
js回到页面指定位置的三种方式
2020/12/17 Javascript
python实现自动登录人人网并访问最近来访者实例
2014/09/26 Python
python读取excel表格生成erlang数据
2017/08/26 Python
解决出现Incorrect integer value: '' for column 'id' at row 1的问题
2017/10/29 Python
Python数据分析之获取双色球历史信息的方法示例
2018/02/03 Python
Python单元和文档测试实例详解
2019/04/11 Python
python实现文件的备份流程详解
2019/06/18 Python
Pandas中Series和DataFrame的索引实现
2019/06/27 Python
程序员的七夕用30行代码让Python化身表白神器
2019/08/07 Python
python logging设置level失败的解决方法
2020/02/19 Python
Python将字典转换为XML的方法
2020/08/01 Python
python爬虫使用scrapy注意事项
2020/11/23 Python
HTML5 Canvas的性能提高技巧经验分享
2013/07/02 HTML / CSS
Boom手表官网:瑞典手表品牌,设计你的手表
2019/03/11 全球购物
设计总监岗位职责
2013/12/07 职场文书
家长给老师的道歉信
2014/01/13 职场文书
执行总经理岗位职责
2014/02/03 职场文书
合作协议书怎么写
2014/04/18 职场文书
优秀团员事迹材料1500字
2014/08/31 职场文书
oracle表分区的概念及操作
2021/04/24 Oracle
图神经网络GNN算法
2022/05/11 Python