详解如何构建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 DOM编程实例(智播客学习)
Nov 23 Javascript
jquery 获取表单元素里面的值示例代码
Jul 28 Javascript
Jquery 跨域访问 Lightswitch OData Service的方法
Sep 11 Javascript
判断JS对象是否拥有某种属性的两种方式
Dec 02 Javascript
javascript中Array()数组函数详解
Aug 23 Javascript
AngularJS控制器详解及示例代码
Aug 16 Javascript
jQuery实现的无缝广告图片左右滚动功能详解
Dec 24 Javascript
Angularjs分页查询的实现
Feb 24 Javascript
Vue组件中prop属性使用说明实例代码详解
May 31 Javascript
javascript实现文本框标签验证的实例代码
Oct 14 Javascript
vue中axios的二次封装实例讲解
Oct 14 Javascript
WEEX环境搭建与入门详解
Oct 16 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
ajax+php打造进度条 readyState各状态
2010/03/20 PHP
PHP文件上传之多文件上传的实现思路
2016/01/27 PHP
php时间计算相关问题小结
2016/05/09 PHP
Smarty模板引擎缓存机制详解
2016/05/23 PHP
php连接MSsql server的五种方法总结
2018/03/04 PHP
PHP的imageTtfText()函数深入详解
2021/03/03 PHP
Prototype1.5 rc2版指南最后一篇之Position
2007/01/10 Javascript
Javascript 按位与运算符 (&)使用介绍
2014/02/04 Javascript
Jquery 实现图片轮换
2015/01/28 Javascript
javascript实现可全选、反选及删除表格的方法
2015/05/15 Javascript
jQuery实现右侧显示可向左滑动展示的深色QQ客服效果代码
2015/10/23 Javascript
深入理解JavaScript程序中内存泄漏
2016/03/17 Javascript
jQuery文字轮播特效
2017/02/12 Javascript
jquery Form轻松实现文件上传
2017/05/24 jQuery
JavaScript学习总结(一) ECMAScript、BOM、DOM(核心、浏览器对象模型与文档对象模型)
2018/01/07 Javascript
Vue中$refs的用法详解
2018/06/24 Javascript
vue中引用swiper轮播插件的教程详解
2018/08/16 Javascript
微信小程序引用iconfont图标的方法
2018/10/22 Javascript
解决vue.js中settimeout遇到的问题(时间参数短效果不稳定)
2020/07/21 Javascript
python中pylint使用方法(pylint代码检查)
2018/04/06 Python
Pycharm设置去除显示的波浪线方法
2018/10/28 Python
解决Python pandas plot输出图形中显示中文乱码问题
2018/12/12 Python
对python中if语句的真假判断实例详解
2019/02/18 Python
PyTorch 随机数生成占用 CPU 过高的解决方法
2020/01/13 Python
PyTorch笔记之scatter()函数的使用
2020/02/12 Python
西班牙创意礼品和小工具网上商店:Curiosite
2016/07/26 全球购物
英国最大的宠物商店:Pets at Home
2019/04/17 全球购物
M.M.LaFleur官网:美国职业女装品牌
2020/10/27 全球购物
Android面试题及答案
2015/09/04 面试题
什么是用户模式(User Mode)与内核模式(Kernel Mode) ?
2015/09/07 面试题
营业员实习自我鉴定
2013/12/07 职场文书
交通安全寄语大全
2014/04/08 职场文书
南京青奥会口号
2014/06/12 职场文书
党的群众路线教育实践活动个人对照检查材料(公安)
2014/11/05 职场文书
vue实现同时设置多个倒计时
2021/05/20 Vue.js
手残删除python之后的补救方法
2021/06/26 Python