详解如何构建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 相关文章推荐
找到一点可怜的关于dojo资料,谢谢作者!
Dec 06 Javascript
ext监听事件方法[初级篇]
Apr 27 Javascript
javascript Array.sort() 跨浏览器下需要考虑的问题
Dec 07 Javascript
javascript字符串拼接的效率问题
Dec 25 Javascript
全面解析Bootstrap图片轮播效果
Dec 03 Javascript
javascript内存分配原理实例分析
Apr 10 Javascript
详谈js中标准for循环与foreach(for in)的区别
Nov 02 Javascript
vue2.0 实现页面导航提示引导的方法
Mar 13 Javascript
vue-better-scroll 的使用实例代码详解
Dec 03 Javascript
layui数据表格 table.render 报错的解决方法
Sep 29 Javascript
js实现轮播图效果 纯js实现图片自动切换
Aug 09 Javascript
详解Vue的异步更新实现原理
Dec 22 Vue.js
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
DC漫画《蝙蝠侠和猫女》图透 猫女怀孕老爷当爹
2020/04/09 欧美动漫
PHP三层结构(上) 简单三层结构
2010/07/04 PHP
PHP PDOStatement对象bindpram()、bindvalue()和bindcolumn之间的区别
2014/11/20 PHP
Zend Guard使用指南及问题处理
2015/01/07 PHP
PHP调用接口用post方法传送json数据的实例
2018/05/31 PHP
PHP中通过getopt解析GNU C风格命令行选项
2019/11/18 PHP
Js+Jq获取URL参数的集中方法示例代码
2014/05/20 Javascript
jQuery实现仿Google首页拖动效果的方法
2015/05/04 Javascript
通过实例理解javascript中没有函数重载的概念
2015/06/03 Javascript
jquery实现的代替传统checkbox样式插件
2015/06/19 Javascript
浅谈layer的iframe弹窗给里面的标签赋值的问题
2016/11/10 Javascript
提高JavaScript执行效率的23个实用技巧
2017/03/01 Javascript
详解滑动穿透(锁body)终极探索
2019/04/16 Javascript
Element-Ui组件 NavMenu 导航菜单的具体使用
2019/10/24 Javascript
[01:44]《为梦想出发》—联想杯DOTA2完美世界全国高校联赛
2015/09/30 DOTA
在Debian下配置Python+Django+Nginx+uWSGI+MySQL的教程
2015/04/25 Python
Python错误: SyntaxError: Non-ASCII character解决办法
2017/06/08 Python
浅谈scrapy 的基本命令介绍
2017/06/13 Python
Python断言assert的用法代码解析
2018/02/03 Python
python实现随机漫步方法和原理
2019/06/10 Python
Python爬虫库BeautifulSoup获取对象(标签)名,属性,内容,注释
2020/01/25 Python
Python3实现打印任意宽度的菱形代码
2020/04/12 Python
解决TensorFlow训练模型及保存数量限制的问题
2021/03/03 Python
HTML5 自动聚焦(autofocus)属性使用介绍
2013/08/07 HTML / CSS
美国孩之宝玩具官网:Hasbro Pulse
2019/06/24 全球购物
XML文档定义有几种形式?它们之间有何本质区别?解析XML文档有哪几种方式?
2016/01/12 面试题
生物科学系大学生的自我评价
2013/12/20 职场文书
工地质量标语
2014/06/12 职场文书
会计工作总结范文2014
2014/12/23 职场文书
2016年党员创先争优公开承诺书
2016/03/25 职场文书
sql中mod()函数取余数的用法
2021/05/29 SQL Server
Java并发编程之Executor接口的使用
2021/06/21 Java/Android
html form表单基础入门案例讲解
2021/07/15 HTML / CSS
常用的MongoDB查询语句的示例代码
2021/07/25 MongoDB
利用python做数据拟合详情
2021/11/17 Python
SQL注入详解及防范方法
2021/12/06 MySQL