详解如何构建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弹出填写提示效果代码
Apr 16 Javascript
from 表单提交返回值用post或者是get方法实现
Aug 21 Javascript
setTimeout()递归调用不加引号出错的解决方法
Sep 05 Javascript
基于BootStrap Metronic开发框架经验小结【四】Bootstrap图标的提取和利用
May 12 Javascript
动态更新highcharts数据的实现方法
May 28 Javascript
完美实现八种js焦点轮播图(下篇)
Apr 20 Javascript
利用JQuery直接调用asp.net后台的简单方法
Oct 27 Javascript
详解JS中的attribute属性
Apr 25 Javascript
vue.js中引入vuex储存接口数据及调用的详细流程
Dec 14 Javascript
Vue实现双向绑定的原理以及响应式数据的方法
Jul 02 Javascript
JS数组去重详情
Nov 07 Javascript
vue3获取当前路由地址
Feb 18 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中去除所有js,html,css代码
2010/10/12 PHP
检查php文件中是否含有bom的函数
2012/05/31 PHP
php 邮件发送问题解决
2014/03/22 PHP
PHP实现HTML生成PDF文件的方法
2014/11/07 PHP
PHP内核探索之解释器的执行过程
2015/12/22 PHP
PHP未登录自动跳转到登录页面
2016/12/21 PHP
Input 特殊事件onpopertychange和oninput
2009/06/17 Javascript
在Ajax中使用Flash实现跨域数据读取的实现方法
2010/12/02 Javascript
javascript arguments使用示例
2014/12/16 Javascript
轻松创建nodejs服务器(10):处理POST请求
2014/12/18 NodeJs
jQuery实现动态添加和删除一个div
2015/08/12 Javascript
jquery京东商城双11焦点图多图广告特效代码分享
2015/09/06 Javascript
jQuery中inArray方法注意事项分析
2016/01/25 Javascript
Nodejs中的this详解
2016/03/26 NodeJs
JS获取及验证开始结束日期的方法
2016/08/20 Javascript
JS+HTML5实现的前端购物车功能插件实例【附demo源码下载】
2016/10/17 Javascript
Angular.js自动化测试之protractor详解
2017/07/07 Javascript
浅谈FastClick 填坑及源码解析
2018/03/02 Javascript
vue 解决循环引用组件报错的问题
2018/09/06 Javascript
浅谈vuex的基本用法和mapaction传值问题
2019/11/08 Javascript
Python实现类继承实例
2014/07/04 Python
Python中Iterator迭代器的使用杂谈
2016/06/20 Python
python3制作捧腹网段子页爬虫
2017/02/12 Python
python微信公众号开发简单流程
2018/03/23 Python
Python使用一行代码获取上个月是几月
2018/08/30 Python
python命令 -u参数用法解析
2019/10/24 Python
解决Python图形界面中设置尺寸的问题
2020/03/05 Python
用python按照图像灰度值统计并筛选图片的操作(PIL,shutil,os)
2020/06/04 Python
CHARLES & KEITH澳大利亚官网:新加坡时尚品牌
2019/01/22 全球购物
证婚人搞笑证婚词
2014/01/10 职场文书
青年文明号服务承诺
2014/03/31 职场文书
求职信标题怎么写
2014/05/26 职场文书
企业口号大全
2014/06/12 职场文书
社区党建工作汇报材料
2014/10/27 职场文书
担保贷款承诺书
2015/04/30 职场文书
2016七夕情人节寄语
2015/12/04 职场文书