详解如何构建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 相关文章推荐
js 巧妙去除数组中的重复项
Jan 25 Javascript
javascript学习笔记(十七) 检测浏览器插件代码
Jun 20 Javascript
javascript实现设置、获取和删除Cookie的方法
Jun 01 Javascript
jQuery动态星级评分效果实现方法
Aug 06 Javascript
javascript实现的猜数小游戏完整实例代码
May 10 Javascript
基于JS如何实现给字符加千分符(65,541,694,158)
Aug 03 Javascript
js实现表单及时验证功能 用户信息立即验证
Sep 13 Javascript
JavaScript实现图片本地预览功能【不用上传至服务器】
Sep 20 Javascript
react 实现页面代码分割、按需加载的方法
Apr 03 Javascript
详解如何在你的Vue项目配置vux
Jun 04 Javascript
layui加载表格,绑定新增,编辑删除,查看按钮事件的例子
Sep 06 Javascript
javascript实现蒙版与禁止页面滚动
Jan 11 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+MYSQL 出现乱码的解决方法
2008/08/08 PHP
PHP查询数据库中满足条件的记录条数(两种实现方法)
2013/01/29 PHP
PHP运行SVN命令显示某用户的文件更新记录的代码
2014/01/03 PHP
PHP实现多图片上传类实例
2014/07/26 PHP
PHP中file_get_contents高?用法实例
2014/09/24 PHP
如何使用PHP Embed SAPI实现Opcodes查看器
2015/11/10 PHP
php支持断点续传、分块下载的类
2016/05/02 PHP
js资料toString 方法
2007/03/13 Javascript
40个有创意的jQuery图片和内容滑动及弹出插件收藏集之二
2011/12/31 Javascript
js实现拖拽上传图片功能
2017/08/01 Javascript
解决node修改后需频繁手动重启的问题
2018/05/13 Javascript
webpack4 SCSS提取和懒加载的示例
2018/09/03 Javascript
详解基于vue-cli3.0如何构建功能完善的前端架子
2018/10/09 Javascript
vue-cli项目配置多环境的详细操作过程
2018/10/30 Javascript
vue 实现搜索的结果页面支持全选与取消全选功能
2019/05/10 Javascript
微信小程序左右滚动公告栏效果代码实例
2019/09/16 Javascript
[01:01:23]完美世界DOTA2联赛PWL S2 Forest vs FTD.C 第一场 11.26
2020/11/30 DOTA
python使用wxpython开发简单记事本的方法
2015/05/20 Python
python+pandas生成指定日期和重采样的方法
2018/04/11 Python
Python实现的逻辑回归算法示例【附测试csv文件下载】
2018/12/28 Python
Python使用sax模块解析XML文件示例
2019/04/04 Python
Python简易版停车管理系统
2019/08/12 Python
Python OpenCV图像指定区域裁剪的实现
2019/10/30 Python
python一些性能分析的技巧
2020/08/30 Python
Django项目创建及管理实现流程详解
2020/10/13 Python
html5记忆翻牌游戏实现思路及代码
2013/07/25 HTML / CSS
NBA欧洲商店(英国):NBA Europe Store UK
2018/07/27 全球购物
英国名牌服装购物网站:OD’s Designer
2019/09/02 全球购物
飞利浦美国官网:Philips美国
2020/02/28 全球购物
数学系个人求职信范文
2014/01/30 职场文书
会计电算化毕业生自荐信
2014/03/03 职场文书
团日活动总结范文
2014/04/25 职场文书
送温暖献爱心活动总结
2014/07/08 职场文书
仲裁协议书
2014/09/26 职场文书
2019银行员工个人工作自我鉴定
2019/06/27 职场文书
vue响应式原理与双向数据的深入解析
2021/06/04 Vue.js