详解如何构建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 使用手册(三)
Sep 23 Javascript
jquery EasyUI的formatter格式化函数代码
Jan 12 Javascript
通过Jquery遍历Json的两种数据结构的实现代码
Jan 19 Javascript
解析JavaScript中点号“.”的多义性
Dec 02 Javascript
JS实现的在线调色板实例(附demo源码下载)
Mar 01 Javascript
第一次接触神奇的Bootstrap导航条
Aug 09 Javascript
webpack 打包压缩js和css的方法示例
Mar 20 Javascript
基于Vue2x的图片预览插件的示例代码
May 14 Javascript
详解React中传入组件的props改变时更新组件的几种实现方法
Sep 13 Javascript
vue添加axios,并且指定baseurl的方法
Sep 19 Javascript
学习LayUI时自研的表单参数校验框架案例分析
Jul 29 Javascript
springboot+VUE实现登录注册
May 27 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
php实现的在线人员函数库
2008/04/09 PHP
php xml文件操作代码(一)
2009/03/20 PHP
php中使用临时表查询数据的一个例子
2013/02/03 PHP
使用php检测用户当前使用的浏览器是否为IE浏览器
2013/12/03 PHP
php获取文件内容最后一行示例
2014/01/09 PHP
PHP array_key_exists检查键名或索引是否存在于数组中的实现方法
2016/06/13 PHP
prototype class详解
2006/09/07 Javascript
javascript脚本调试方法小结
2008/11/24 Javascript
javascript iframe内的函数调用实现方法
2009/07/19 Javascript
jQuery帮助之CSS尺寸(五)outerHeight、outerWidth
2009/11/14 Javascript
写出更好的JavaScript程序之undefined篇(中)
2009/11/23 Javascript
JavaScript中的变量声明早于赋值分析
2012/03/01 Javascript
Egret引擎开发指南之运行项目
2014/09/03 Javascript
js 获取元素在页面上的偏移量的方法汇总
2015/04/13 Javascript
Javascript非构造函数的继承
2015/04/27 Javascript
jQuery获得字体颜色16位码的方法
2016/02/20 Javascript
彻底学会Angular.js中的transclusion
2017/03/12 Javascript
Vue中定义全局变量与常量的各种方式详解
2017/08/23 Javascript
js中json对象和字符串的理解及相互转化操作实现方法
2017/09/22 Javascript
详解javascript设计模式三:代理模式
2019/03/25 Javascript
javascript function(函数类型)使用与注意事项小结
2019/06/10 Javascript
详解BootStrap表单验证中重置BootStrap-select验证提示不清除的坑
2019/09/17 Javascript
基于Python_脚本CGI、特点、应用、开发环境(详解)
2017/05/23 Python
python hook监听事件详解
2018/10/25 Python
Python模块的加载讲解
2019/01/15 Python
selenium设置浏览器为headless无头模式(Chrome和Firefox)
2021/01/08 Python
纯CSS3实现鼠标悬停提示气泡效果
2014/02/28 HTML / CSS
CSS3中线性颜色渐变的一些实现方法
2015/07/14 HTML / CSS
编写strcpy函数
2014/06/24 面试题
祖国在我心中演讲稿500字
2014/05/04 职场文书
教师读书活动总结
2014/05/07 职场文书
安全伴我行演讲稿
2014/09/04 职场文书
寒山寺导游词
2015/02/03 职场文书
该怎么书写道歉信?
2019/07/03 职场文书
go结构体嵌套的切片数组操作
2021/04/28 Golang
一篇带你入门Java垃圾回收器
2021/06/16 Java/Android