详解如何构建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 相关文章推荐
javascript 面向对象编程 function也是类
Sep 17 Javascript
在Firefox下js select标签点击无法弹出
Mar 06 Javascript
项目中常用的JS方法整理
Jan 30 Javascript
JavaScript实现非常简单实用的下拉菜单效果
Aug 27 Javascript
JavaScrip调试技巧之断点调试
Oct 22 Javascript
javaScript事件学习小结(四)event的公共成员(属性和方法)
Jun 09 Javascript
Jquery循环截取字符串的方法(多出的字符串处理成"...")
Nov 28 Javascript
微信小程序 开发之顶部导航栏实例代码
Feb 23 Javascript
详解在Angular项目中添加插件ng-bootstrap
Jul 04 Javascript
用vue快速开发app的脚手架工具
Jun 11 Javascript
JavaScript实现指定数量的并发限制的示例代码
Mar 10 Javascript
Vue ECharts实现机舱座位选择展示功能
May 15 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抓取、分析国内视频网站的视频信息工具类
2014/04/02 PHP
php的ddos攻击解决方法
2015/01/08 PHP
Laravel 5框架学习之表单验证
2015/04/08 PHP
php求数组全排列,元素所有组合的方法总结
2017/03/14 PHP
laravel框架关于搜索功能的实现
2018/03/15 PHP
Gambit vs CL BO3 第二场 2.13
2021/03/10 DOTA
我也种棵OO树JXTree[js+css+xml]
2007/04/02 Javascript
WordPress 插件——CoolCode使用方法与下载
2007/07/02 Javascript
jquery应该如何来设置改变按钮input的onclick事件
2012/12/10 Javascript
Extjs4 GridPanel 的几种样式使用介绍
2013/04/18 Javascript
JavaScript判断是否为数字的4种方法及效率比较
2015/04/01 Javascript
JQuery球队选择实例
2015/05/18 Javascript
JavaScript实现下拉列表框数据增加、删除、上下排序的方法
2015/08/11 Javascript
jquery的幻灯片图片切换效果代码分享
2015/09/07 Javascript
JavaScript中点击事件的写法
2016/06/28 Javascript
jQuery+ajax实现实用的点赞插件代码
2016/07/06 Javascript
谈谈JavaScript的New关键字
2016/08/26 Javascript
鼠标经过出现气泡框的简单实例
2017/03/17 Javascript
AngularJS 表单验证手机号的实例(非必填)
2017/11/12 Javascript
基于vue打包后字体和图片资源失效问题的解决方法
2018/03/06 Javascript
nodejs实现日志读取、日志查找及日志刷新的方法分析
2019/05/20 NodeJs
vue实现pdf文档在线预览功能
2019/11/26 Javascript
[01:07]DOTA2次级职业联赛 - Fpb战队宣传片
2014/12/01 DOTA
[01:01:42]Secret vs Optic Supermajor 胜者组 BO3 第二场 6.4
2018/06/05 DOTA
[01:00] DOTA2英雄背景故事第五期之重力引力法则谜团
2020/07/16 DOTA
Python Logging 日志记录入门学习
2018/06/02 Python
TensorFlow查看输入节点和输出节点名称方式
2020/01/04 Python
python3.6连接mysql数据库及增删改查操作详解
2020/02/10 Python
python 实现有道翻译功能
2021/02/26 Python
旅游管理毕业生自荐信
2013/11/05 职场文书
大学毕业生自我鉴定
2013/11/05 职场文书
师德师风建设方案
2014/05/08 职场文书
科级干部群众路线教育实践活动对照检查材料思想汇报
2014/09/20 职场文书
再婚婚前财产协议书范本
2014/10/19 职场文书
大学生预备党员自我评价
2015/03/04 职场文书
民事调解协议书
2016/03/21 职场文书