详解如何构建Promise队列实现异步函数顺序执行

场景

有a、b、c三个异步任务,要求必须先执行a,再执行b,最后执行c

且下一次任务必须要拿到上一次任务执行的结果,才能做操作

思路

我们需要实现一个队列,将这些异步函数添加进队列并且管理它们的执行,队列具有First In First Out的特性,也就是先添加进去的会被先执行,接着才会执行下一个(注意跟栈作区别)

大家也可以类比一下jQuery的animate方法,添加多个动画也会按顺序执行

解决

模拟3个异步函数

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

// 异步函数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链式操作)

特点:可以满足需求,但是书写比较繁琐

代码

?


1

2

3

4

5

6

7

8

9

10

11

//链式调用

a()

 .then(function (data) {

  return b(data)

 })

 .then(function (data) {

  return c(data)

 })

 .then(function (data) {

  console.log(data)// abc

 })

方法二(构建队列)

特点:封装方法,可移植到别处使用

代码

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

// 构建队列

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构建队列)

同方法二,只是显得更高大上点

代码

?


1

2

3

4

5

6

7

8

9

10

11

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对象,都可以使用。

     
李炎恢jQuery视频教程 
html5移动app开发框架jqueryMobile视频教程 
兄弟连HTML5+css3视频教程 
HTML5网页设计入门系列课程 
后盾网html5视频教程 
HTML5+css3实例讲解 
React高级实战 – 打造大众点评 WebApp 
ES6零基础教学 解析彩票项目   ...2
2017 Javascript基础到精通 23课 附课件源码
WEB前端开发零基础入门到项目实战练习 18课
MUI+HTML5开发webapp技术
移动前端跨平台技术——ES6基础+React Native项目实战
主流JsUI框架 后台开发必备jQuery Easyui 视频教程 13课
HTML5教程从入门到精通及网站源码
Javascript ES6 实战视频课程
李炎恢JQuery EasyUI视频培训视频教程
李炎恢Bootstrap视频教程
李炎恢老师HTML5+CSS3教程与课件代码
李炎恢老师XHTML视频教程DIV+CSS教程与课件代码
彻底征服React.js + Flux + Redux 

原文地址:https://www.cnblogs.com/xanthedsf/p/10163997.html

时间: 2024-08-01 16:38:24

详解如何构建Promise队列实现异步函数顺序执行的相关文章

【java项目实践】详解Ajax工作原理以及实现异步验证用户名是否存在+源码下载(java版)

一年前,从不知道Ajax是什么,伴随着不断的积累,到现在经常使用,逐渐有了深入的认识.今天,如果想开发一个更加人性化,友好,无刷新,交互性更强的网页,那您的目标一定是Ajax. 介绍 在详细讨论Ajax是什么之前,先让我们花一分钟了解一下Ajax做什么.如图所示: 如上图展示给我们的就是使用Ajax技术实现的效果.伴随着web应用的越来越强大而出现的是等待,等待服务器响应,等待浏览器刷新,等待请求返回和生成新的页面成为了程序员们的最最头疼的难题.随着Ajax的出现使web应用程序变得更完善,更友

详解C#委托,事件与回调函数

.Net编程中最经常用的元素,事件必然是其中之一.无论在ASP.NET还是WINFrom开发中,窗体加载(Load),绘制(Paint),初始化(Init)等等.“protected void Page_Load(object sender, EventArgs e)”这段代码相信没有人不熟悉的.细心一点一定会发现,非常多的事件方法都是带了“object sender, EventArgs e”这两个参数.这是不是和委托非常相似呢? 一.委托(有些书中也称为委派) 委托是什么呢?这个名字的意思已

关于多个Promise对象及then()函数的执行顺序的研究记录

今天终于想要研究一下多个 Promise 对象的执行顺序问题了,在研究完后记录一下. 我想研究的是以下问题: 1.多个 Promise 对象及其then函数的执行顺序,这里不研究处于不同状态的 Promise 对象的执行顺序 2.在 Promise 中的定时器延时问题(这个问题其实在 MDN 和阮一峰老师的 ES6 入门中都讲过,只是我光看文字有点晕,所以自己写代码来理解) 废话不多说,先上代码吧 // 延时执行 new Promise(resolve => setTimeout(() =>

详解linux进程间通信-消息队列

前言:前面讨论了信号.管道的进程间通信方式,接下来将讨论消息队列. 一.系统V IPC 三种系统V IPC:消息队列.信号量以及共享内存(共享存储器)之间有很多相似之处. 每个内核中的 I P C结构(消息队列.信号量或共享存储段)都用一个非负整数的标识符( i d e n t i f i e r )加以引用. 无论何时创建I P C结构(调用m s g g e t. s e m g e t或s h m g e t) ,都应指定一个关键字(k e y),关键字的数据类型由系统规定为 k e y

JavaScript正则表达式详解(二)JavaScript中正则表达式函数详解

二.JavaScript中正则表达式函数详解(exec, test, match, replace, search, split) 1.使用正则表达式的方法去匹配查找字符串 1.1. exec方法详解 exec方法的返回值 exec方法返回的其实并不是匹配结果字符串,而是一个对象,简单地修改一下execReg函数,来做一个实验就可以印证这一点: function execReg(reg, str) { var result = reg.exec(str); alert(typeof result

详解JavaScript中的replace()函数

Javascript中字符串对象有一个方法replace(),它的作用非常强大.这里把它的用法整理一下.  一.方法简介 该方法的签名是:replace([RegExp|String],[String|Function]). 该方法 返回一个新的字符串,但并不改变字符串本身. 该方法接收2个参数,第一个参数可以是字符串,也可以是一个正则表达式:第二个参数可以是一个字符串,也可以是一个函数.其中第2个参数如果是函数,那么用起来是十分强大而且灵活的,不过相对来说也比较难掌握.下面就其用法进行详细说明

详解vue父组件传递props异步数据到子组件的问题

案例一 父组件parent.vue // asyncData为异步获取的数据,想传递给子组件使用 <template> <div> 父组件 <child :child-data="asyncData"></child> </div> </template> <script> import child from './child' export default { data: () => ({ as

Callback函数详解(我感觉,回掉函数的本质是函数指针,在业务做循环处理的时候,调用一下通知外部)

2010年的最后一天了,转载一篇自己认为还不错的文章与大家分享.希望对大家有所帮助. 一,回调函数 我们经常在C++设计时通过使用回调函数可以使有些应用(如定时器事件回调处理.用回调函数记录某操作进度等)变得非常方便和符合逻辑,那么它的内在机制如何呢,怎么定义呢?它和其它函数(比如钩子函数)有何不同呢? 使用回调函数实际上就是在调用某个函数(通常是API函数)时,将自己的一个函数(这个函数为回调函数)的地址作为参数传递给那个函数. 而那个函数在需要的时候,利用传递的地址调用回调函数,这时你可以利

02 详解主流浏览器多个外部JS请求和执行机制

在IE8.Firefox3.6之前页面加载外部的javascript文件(IE6和IE7会连同图片,样式资源和页面渲染一同阻塞)是阻塞式的,而在之后的版本中,浏览器都使用了瀑布式加载,这样页面的打开及渲染速度都会变快,请注意,我提到的瀑布式加载,仅仅指的是加载,而非JS的执行,在主流浏览器中JS的执行总是阻塞的.用简单一点的语言描述,就是同一时间,页面只会加载一个js文件.在第一个js文件加载并执行完之前,第二个要引入的js不会下载和执行.而页面中js的引入顺序以请求的顺序为定. 我们来看一个在