详解如何构建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下:nth-child(an+b)的使用注意
May 28 Javascript
JS正则中的RegExp对象对象
Nov 07 Javascript
Js 回车换行处理的办法及replace方法应用
Jan 24 Javascript
基于jQuery中对数组进行操作的方法
Apr 16 Javascript
浅析JavaScript中的隐式类型转换
Dec 05 Javascript
如何在指定的地方插入html内容和文本内容
Dec 23 Javascript
jQuery实现可展开合拢的手风琴面板菜单
Sep 15 Javascript
利用Angularjs和bootstrap实现购物车功能
Aug 31 Javascript
详解vue中使用protobuf踩坑记
May 07 Javascript
微信小程序canvas开发水果老虎机的思路详解
Feb 07 Javascript
JavaScript实现打砖块游戏
Feb 25 Javascript
vue v-for出来的列表,点击某个li使得当前被点击的li字体变红操作
Jul 17 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
介绍几个array库的新函数 php
2006/12/29 PHP
PHP中空字符串介绍0、null、empty和false之间的关系
2012/09/25 PHP
5种PHP创建数组的实例代码分享
2014/01/17 PHP
php中实现可以返回多个值的函数实例
2015/03/21 PHP
PHP获取二维数组中某一列的值集合
2015/12/25 PHP
PHP获取input输入框中的值去数据库比较显示出来
2016/11/16 PHP
yii2 开发api接口时优雅的处理全局异常的方法
2019/05/14 PHP
制作特殊字的脚本
2006/06/26 Javascript
JS构建页面的DOM节点结构的实现代码
2011/12/09 Javascript
JS操作CSS随机改变网页背景实现思路
2014/03/10 Javascript
JavaScript改变CSS样式的方法汇总
2015/05/07 Javascript
JavaScript如何调试有哪些建议和技巧附五款有用的调试工具
2015/10/28 Javascript
详解Matlab中 sort 函数用法
2016/03/20 Javascript
jQuery EasyUI 页面加载等待及页面等待层
2017/02/06 Javascript
Javascript之深入浅出prototype
2017/02/06 Javascript
JS解决移动web开发手机输入框弹出的问题
2017/03/31 Javascript
ES6学习笔记之正则表达式和字符串正则方法分析
2017/04/25 Javascript
bootstrap 点击空白处popover弹出框隐藏实例
2018/01/24 Javascript
vue.js中toast用法及使用toast弹框的实例代码
2018/08/27 Javascript
JavaScript栈和队列相关操作与实现方法详解
2018/12/07 Javascript
python整合ffmpeg实现视频文件的批量转换
2019/05/31 Python
无惧面试,带你搞懂python 装饰器
2020/08/17 Python
利用python批量爬取百度任意类别的图片的实现方法
2020/10/07 Python
Python3中FuzzyWuzzy库实例用法
2020/11/18 Python
详解使用CSS3的@media来编写响应式的页面
2017/11/01 HTML / CSS
美国最大的宠物药店:1-800-PetMeds
2016/10/02 全球购物
使用索引(Index)有哪些需要考虑的因素
2016/10/19 面试题
英语演讲稿范文
2014/01/03 职场文书
机械工程学院大学生求职信
2014/05/25 职场文书
2014年大学班级工作总结
2014/11/14 职场文书
盗窃案辩护词
2015/05/21 职场文书
信仰纪录片观后感
2015/06/08 职场文书
厉行节约工作总结
2015/08/12 职场文书
办公室主任岗位竞聘书
2015/09/15 职场文书
CSS实现两列布局的N种方法
2021/08/02 HTML / CSS
html,css,javascript是怎样变成页面的
2023/05/07 HTML / CSS