详解如何构建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-简单的日历实现及Date对象语法介绍(附图)
May 30 Javascript
Jquery获取和修改img的src值的方法
Feb 17 Javascript
一个简单的实现下拉框多选的插件可移植性比较好
May 05 Javascript
jQuery找出网页上最高元素的方法
Mar 20 Javascript
jquery日历插件datepicker用法分析
Jan 22 Javascript
jQuery 3.0中存在问题及解决办法
Jul 15 Javascript
angular route中使用resolve在uglify压缩后问题解决
Sep 21 Javascript
Angular实现响应式表单
Aug 04 Javascript
Cropper.js 实现裁剪图片并上传(PC端)
Aug 20 Javascript
weui框架实现上传、预览和删除图片功能代码
Aug 24 Javascript
vue v-for循环重复数据无法添加问题解决方法【加track-by='索引'】
Mar 15 Javascript
探索node之事件循环的实现
Oct 30 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 Undefined index报错的修复方法
2011/07/17 PHP
php中preg_match的isU代表什么意思
2015/10/01 PHP
php设计模式之适配器模式实例分析【星际争霸游戏案例】
2020/04/07 PHP
PHP tp5中使用原生sql查询代码实例
2020/10/28 PHP
javascript函数中的arguments参数
2010/08/01 Javascript
jquery的总体架构分析及实现示例详解
2014/11/08 Javascript
JavaScript 异常处理 详解
2015/02/06 Javascript
jquery实现弹出层登录和全屏层注册特效
2015/08/28 Javascript
JavaScript精炼之构造函数 Constructor及Constructor属性详解
2015/11/05 Javascript
javascript中利用柯里化函数实现bind方法
2016/04/29 Javascript
jQuery实现Select下拉列表进行状态选择功能
2017/03/30 jQuery
Javascript中八种遍历方法的执行速度深度对比
2017/04/25 Javascript
import与export在node.js中的使用详解
2017/09/28 Javascript
如何更好的编写js async函数
2018/05/13 Javascript
基于jQuery拖拽事件的封装
2020/11/29 jQuery
python登录豆瓣并发帖的方法
2015/07/08 Python
Python编程之黑板上排列组合,你舍得解开吗
2017/10/30 Python
python的pandas工具包,保存.csv文件时不要表头的实例
2018/06/14 Python
python的scikit-learn将特征转成one-hot特征的方法
2018/07/10 Python
numpy中loadtxt 的用法详解
2018/08/03 Python
Python Opencv提取图片中某种颜色组成的图形的方法
2019/09/19 Python
基于python调用psutil模块过程解析
2019/12/20 Python
500行python代码实现飞机大战
2020/04/24 Python
PyTorch之nn.ReLU与F.ReLU的区别介绍
2020/06/27 Python
详解Flask前后端分离项目案例
2020/07/24 Python
基于Python中Remove函数的用法讨论
2020/12/11 Python
使用CSS3和Checkbox实现JQuery的一些效果
2015/08/03 HTML / CSS
经典c++面试题三
2015/07/08 面试题
.NET里面什么时候需要调用垃圾回收
2015/06/01 面试题
大四自我鉴定范文
2013/10/06 职场文书
高中毕业自我鉴定
2013/12/16 职场文书
中秋节国旗下演讲稿
2014/09/13 职场文书
2014业务员年终工作总结
2014/12/09 职场文书
反腐倡廉影片观后感
2015/06/08 职场文书
2016年6.5世界环境日宣传活动总结
2016/04/01 职场文书
Pygame游戏开发之太空射击实战敌人精灵篇
2022/08/05 Python