详解如何构建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 相关文章推荐
syntaxhighlighter 使用方法
Jul 02 Javascript
jquery checkbox,radio是否选中的判断代码
Mar 20 Javascript
jQuery 获取对象 定位子对象
May 31 Javascript
移动手机APP手指滑动切换图片特效附源码下载
Nov 30 Javascript
悬浮广告方法日常收集整理
Mar 18 Javascript
第一篇初识bootstrap
Jun 21 Javascript
BootStrap fileinput.js文件上传组件实例代码
Feb 20 Javascript
jQuery利用FormData上传文件实现批量上传
Dec 04 jQuery
jQuery实现动态加载(按需加载)javascript文件的方法分析
May 31 jQuery
VsCode与Node.js知识点详解
Sep 05 Javascript
详解Nuxt.js中使用Element-UI填坑
Sep 06 Javascript
详解CocosCreator消息分发机制
Apr 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极大的增强功能和性能
2006/10/09 PHP
基于mysql的论坛(5)
2006/10/09 PHP
php实现图片缩略图的方法
2016/03/29 PHP
WordPress中设置Post Type自定义文章类型的实例教程
2016/05/10 PHP
Docker搭建自己的PHP开发环境
2018/02/24 PHP
基于jquery的复制网页内容到WORD的实现代码
2011/02/16 Javascript
jquery插件制作 表单验证实现代码
2012/08/17 Javascript
jquery获取被勾选的checked(选中)的那一行的3列和4列的值
2013/07/04 Javascript
firefox浏览器不支持innerText的解决方法
2013/08/07 Javascript
javascript每日必学之运算符
2016/02/16 Javascript
JavaScript 闭包机制详解及实例代码
2016/10/10 Javascript
jQuery基于cookie实现换肤功能实例
2017/10/14 jQuery
bootstrap fileinput插件实现预览上传照片功能
2018/01/23 Javascript
NodeJS安装图文教程
2018/04/19 NodeJs
Vue唯一可以更改vuex实例中state数据状态的属性对象Mutation的讲解
2019/01/18 Javascript
小程序怎样让wx.navigateBack更好用的方法实现
2019/11/01 Javascript
使用preload预加载页面资源时注意事项
2020/02/03 Javascript
[01:56]《DOTA2》中文配音CG
2013/04/22 DOTA
[02:07]2017国际邀请赛中国区预选赛直邀战队前瞻
2017/06/23 DOTA
python中类的一些方法分析
2014/09/25 Python
详解Python的Flask框架中生成SECRET_KEY密钥的方法
2016/06/07 Python
python使用matplotlib绘制热图
2018/11/07 Python
详解Python基础random模块随机数的生成
2019/03/23 Python
python+requests接口压力测试500次,查看响应时间的实例
2020/04/30 Python
Python Socket多线程并发原理及实现
2020/12/11 Python
Python截图并保存的具体实例
2021/01/14 Python
美国校园市场:OCM
2017/06/08 全球购物
香港优质食材和美酒专门店:FoodWise
2017/09/01 全球购物
Aeropostale官网:美国著名校园品牌及青少年服饰品牌
2019/03/21 全球购物
美国排名第一的泳池用品直接来源:In The Swim
2019/09/23 全球购物
什么是抽象
2015/12/13 面试题
民事调解书范文
2015/05/20 职场文书
python基于scrapy爬取京东笔记本电脑数据并进行简单处理和分析
2021/04/14 Python
Django一小时写出账号密码管理系统
2021/04/29 Python
JavaScript中时间格式化新思路toLocaleString()
2021/11/07 Javascript
Python 键盘事件详解
2021/11/11 Python