详解如何构建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 相关文章推荐
Web层改进II-用xmlhttp 无声息提交复杂表单
Jan 22 Javascript
firefox和IE系列的相关区别整理 以备后用
Dec 28 Javascript
jQuery中将函数赋值给变量的调用方法
Mar 23 Javascript
jquery的each方法使用示例分享
Mar 25 Javascript
原生js结合html5制作简易的双色子游戏
Mar 30 Javascript
jQuery插件slider实现拖动滑块选取价格范围
Apr 30 Javascript
基于Jquery实现表单验证
Jul 20 Javascript
Jquery组件easyUi实现选项卡切换示例
Aug 23 Javascript
教你5分钟学会用requirejs(必看篇)
Jul 25 Javascript
基于JavaScript实现新增内容滚动播放效果附完整代码
Aug 24 Javascript
详解node单线程实现高并发原理与node异步I/O
Sep 21 Javascript
vue3.0 CLI - 2.6 - 组件的复用入门教程
Sep 14 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 分页函数multi() discuz
2009/06/21 PHP
php操作redis中的hash和zset类型数据的方法和代码例子
2014/07/05 PHP
基于PHP的简单采集数据入库程序
2014/07/30 PHP
WordPress中用于获取及自定义头像图片的PHP脚本详解
2015/12/17 PHP
PHP文件上传问题汇总(文件大小检测、大文件上传处理)
2015/12/24 PHP
PHP页面输出搜索后跳转下一页的处理方法
2016/09/30 PHP
js 实现在离开页面时提醒未保存的信息(减少用户重复操作)
2013/01/16 Javascript
javascript制作的网页侧边弹出框思路及实现代码
2014/05/21 Javascript
js实现背景图片感应鼠标变化的方法
2015/02/28 Javascript
再次谈论Javascript中的this
2016/06/23 Javascript
JQuery ZTree使用方法详解
2017/01/07 Javascript
JavaScript异步上传图片文件的实例代码
2017/07/04 Javascript
基于Vue实例生命周期(全面解析)
2017/08/16 Javascript
angular.js4使用 RxJS 处理多个 Http 请求
2017/09/23 Javascript
vue webuploader 文件上传组件开发
2017/09/23 Javascript
vue-awesome-swiper滑块插件使用方法详解
2017/11/27 Javascript
vue实现固定位置显示功能
2019/05/30 Javascript
js实现上传图片并显示图片名称
2019/12/18 Javascript
[01:16:28]DOTA2-DPC中国联赛 正赛 iG vs Magma BO3 第二场 2月23日
2021/03/11 DOTA
Python使用Socket(Https)Post登录百度的实现代码
2012/05/18 Python
python fabric使用笔记
2015/05/09 Python
Python中常见的数据类型小结
2015/08/29 Python
用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动
2015/11/05 Python
python+requests+unittest API接口测试实例(详解)
2017/06/10 Python
python生成词云的实现方法(推荐)
2017/06/13 Python
python 实现上传图片并预览的3种方法(推荐)
2017/07/14 Python
5款Python程序员高频使用开发工具推荐
2019/04/10 Python
Python使用LDAP做用户认证的方法
2019/06/20 Python
详解将Python程序(.py)转换为Windows可执行文件(.exe)
2019/07/19 Python
Form表单及django的form表单的补充
2019/07/25 Python
使用python去除图片白色像素的实例
2019/12/12 Python
几个Shell Script面试题
2012/08/31 面试题
节能环保家庭事迹材料
2014/08/27 职场文书
部门2015年度工作总结
2015/04/29 职场文书
Pytorch中expand()的使用(扩展某个维度)
2022/07/15 Python
Windows7下FTP搭建图文教程
2022/08/05 Servers