详解如何构建Promise队列实现异步函数顺序执行
场景
有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对象,都可以使用
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。
相关推荐
-
promise和co搭配生成器函数方式解决js代码异步流程的比较
在es6中引入的原生Promise为js的异步回调问题带来了一个新的解决方式,而TJ大神写的co模块搭配Generator函数的同步写法,更是将js的异步回调带了更优雅的写法. 今天我想对比一下这两种方式,来看看这两种方式的区别以及优劣. 我们先抽象几个操作: 以做饭为例,我们先去买菜,回来洗菜,刷碗,烧菜,最后才是吃.定义如下方法: var buy = function (){}; //买菜,需要3s var clean = function(){}; //洗菜,需要1s var wash =
-
JS中Promise函数then的奥秘探究
Promise概述 Promise对象是CommonJS工作组提出的一种规范,目的是为异步操作提供统一接口. 那么,什么是Promises? 首先,它是一个对象,也就是说与其他JavaScript对象的用法,没有什么两样:其次,它起到代理作用(proxy),充当异步操作与回调函数之间的中介.它使得异步操作具备同步操作的接口,使得程序具备正常的同步运行的流程,回调函数不必再一层层嵌套. 简单说,它的思想是,每一个异步任务立刻返回一个Promise对象,由于是立刻返回,所以可以采用同步操作的流程.这
-
node使用promise替代回调函数
在学习 Node.js 过程中接触到了如何使用 async 来控制并发(使用 async 控制并发) async 的本质是一个流程控制.其实在异步编程中,还有一个更为经典的模型,叫做 Promise/Deferred 模型(当然还有更多相关解决方法,比如 eventproxy,co 等,到时候遇到在挖坑) 首先,我们思考一个典型的异步编程模型,考虑这样一个题目:读取一个文件,在控制台输出这个文件内容 var fs = require('fs'); fs.readFile('1.txt', 'ut
-
详解在微信小程序的JS脚本中使用Promise来优化函数处理
在我们传统的Javascript开发函数编写中,我们习惯了回调函数的处理,不过随着回调函数的增多,以及异步处理的复杂性等原因,代码越来越难读,因此诞生了使用Promise来优化JS函数处理的需求,引入Promise确实能够很好的解决异步回调函数的可读性等问题,同时也使得我们调用的时候代码简洁一些,本文介绍如何在小程序的JS代码里面使用Promise来封装一些函数的做法. 1.小程序传统的回调处理 例如我们生成一个小程序,里面的app.js里面就自动带有一个getUserInfo的函数,这个是使用
-
利用Promise自定义一个GET请求的函数示例代码
写在最前面 近期 review 自己以前的代码的时候,看到 promise 的使用方法,用的比较模糊.含义不清,用法凌乱,这里重新温习一下基础知识. 前言 JavaScript 是单线程工作,但是浏览器是多线程的.为了更好的完成我们程序的任务.Promise 异步的操作就由此诞生了. 一个 Promise 就是一个代表了异步操作最终完成或者失败的结果对象. 怎么使用? 语法 基本 new Promise( function(resolve, reject) {...} /* executor *
-
NodeJS中利用Promise来封装异步函数
在写Node.js的过程中,连续的IO操作可能会导致"金字塔噩梦",回调函数的多重嵌套让代码变的难以维护,利用CommonJs的Promise来封装异步函数,使用统一的链式API来摆脱多重回调的噩梦. Node.js提供的非阻塞IO模型允许我们利用回调函数的方式处理IO操作,但是当需要连续的IO操作时,你的回调函数会多重嵌套,代码很不美观,而且不易维护,而且可能会有许多错误处理的重复代码,也就是所谓的"Pyramid of Doom". 复制代码 代码如下: ste
-
详解如何构建Promise队列实现异步函数顺序执行
场景 有a.b.c三个异步任务,要求必须先执行a,再执行b,最后执行c 且下一次任务必须要拿到上一次任务执行的结果,才能做操作 思路 我们需要实现一个队列,将这些异步函数添加进队列并且管理它们的执行,队列具有First In First Out的特性,也就是先添加进去的会被先执行,接着才会执行下一个(注意跟栈作区别) 大家也可以类比一下jQuery的animate方法,添加多个动画也会按顺序执行 解决 模拟3个异步函数 // 异步函数a var a = function () { return
-
详解ES9的新特性之异步遍历Async iteration
异步遍历 在讲解异步遍历之前,我们先回想一下ES6中的同步遍历. 根据ES6的定义,iteration主要由三部分组成: Iterable 先看下Iterable的定义: interface Iterable { [Symbol.iterator]() : Iterator; } Iterable表示这个对象里面有可遍历的数据,并且需要实现一个可以生成Iterator的工厂方法. Iterator interface Iterator { next() : IteratorResult; } 可
-
详解IOS串行队列与并行队列进行同步或者异步的实例
详解IOS串行队列与并行队列进行同步或者异步的实例 IOS中GCD的队列分为串行队列和并行队列,任务分为同步任务和异步任务,他们的排列组合有四种情况,下面分析这四种情况的工作方式. 同步任务,使用GCD dispatch_sync 进行派发任务 - (void)testSync { dispatch_queue_t serialQueue = dispatch_queue_create("com.zyt.queue", DISPATCH_QUEUE_SERIAL); dispatch_
-
详解python数据结构之队列Queue
一.前言 队列Queue是一种先进先出(FIFO,First In First Out)的线性表.允许一端进行插入(rear),对应的另一段进行删除(front). 本篇包含以下内容: (1)Queue的基本格式 (2)入队列en_queue (3)删除数据函数 de_queue 二.Queue的基本格式 class Queue(): def __init__(self,size): self.size = size self.front = -1 #设置front初始值,每出队列一个数据就加
-
详解Gradle构建过程
Gradle构建过程 根据在上图中所示,Gradle 的构建过程主要分为三个阶段: 初始化阶段 配置阶段 执行阶段 监听Gradle初始化时机 在这个初始化阶段中主要有两个时机需要关注: setting.gradle 执行结束的监听 //1.setting.gradle 执行结束的监听 gradle.settingsEvaluated { println "settings.gradle 初始化执行结束" } 参与构建的Project对象创建完毕的监听 //2.参与构建的Project
-
详解PHP多进程消费队列
目录 引言 nginx进程模型 进程设计 进程信号量设计 PHP安装修信号量 信号量和系统调用 daemon(守护)进程 命令设计 启动命令 强制停止命令 强制重启命令 平滑停止命令 平滑重启命令 查看进程状态 引言 最近开发一个小功能,用到了队列mcq,启动一个进程消费队列数据,后边发现一个进程处理不过来了,又加了一个进程,过了段时间又处理不过来了...... 这种方式每次都要修改crontab,如果进程挂掉了,不会及时的启动,要等到下次crontab执行的时候才会启动.关闭(重启)进程的时候
-
详解Java七大阻塞队列之SynchronousQueue
目录 分析 其实SynchronousQueue 是一个特别有意思的阻塞队列,就我个人理解来说,它很重要的特点就是没有容量. 直接看一个例子: package dongguabai.test.juc.test; import java.util.concurrent.SynchronousQueue; /** * @author Dongguabai * @description * @date 2021-09-01 21:52 */ public class TestSynchronousQu
-
详解SpringBoot集成消息队列的案例应用
目录 背景 方案规划 统一设计 集成Redis消息队列 集成ActiveMQ消息队列 使用示例 背景 最近在对公司开发框架进行优化,框架内涉及到多处入库的日志记录,例如登录日志/操作日志/访问日志/业务执行日志,集成在业务代码中耦合度较高且占用业务操作执行时间,所以准备集成相关消息队列进行代码解耦 方案规划 现有的成熟消息队列组件非常多,例如RabbitMQ,ActiveMQ,Kafka等,考虑到业务并发量不高且框架已经应用于多个项目平稳运行,准备提供基于Redis的消息队列和集成ActiveM
-
详解RabbitMQ中死信队列和延迟队列的使用详解
目录 简介 死信队列 简介 示例 延迟队列 简介 使用场景 简介 本文介绍RabbitMQ的死信队列和延迟队列. 本内容也是Java后端面试中常见的问题. 死信队列 简介 DLX,全称为Dead-Letter-Exchange,可以称之为死信交换器,也有人称之为死信邮箱.当消息在一个队列中变成死信(dead message)之后,它能被重新被发送到另一个交换器中,这个交换器就是DLX,绑定DLX的队列就称之为死信队列. 以下几种情况会导致消息变成死信: 消息被拒绝(Basic.Reject/Ba
-
详解Java线程池队列中的延迟队列DelayQueue
目录 DelayQueue延迟队列 DelayQueue使用场景 DelayQueue属性 DelayQueue构造方法 实现Delayed接口使用示例 DelayQueue总结 在阻塞队里中,除了对元素进行增加和删除外,我们可以把元素的删除做一个延迟的处理,即使用DelayQueue的方法.本文就来和大家聊聊Java线程池队列中的DelayQueue—延迟队列 public enum QueueTypeEnum { ARRAY_BLOCKING_QUEUE(1, "ArrayBlockingQ
随机推荐
- SQLServer 2008 :error 40出现连接错误的解决方法
- Microsoft SQL Server 2008 基本安装说明
- git标签管理_动力节点Java学院整理
- 零基础易语言入门教程(三)之了解控制台程序
- java 数据结构之堆排序(HeapSort)详解及实例
- Linux 7下脚本安装配置oracle 11g r2教程
- VB.NET 中删除DataGridView中所选行的小例子
- php数组声明、遍历、数组全局变量使用小结
- PHP 返回13位时间戳的实现代码
- 第七章之菜单按钮图标组件
- CentOS 7 sshd 链接被拒绝问题解决办法
- PHP session有效期session.gc_maxlifetime
- thinkPHP实现签到功能的方法
- MySQL常用基本SQL语句总结
- 完美解决jQuery符号$与其他javascript 库、框架冲突的问题
- Ajax+Servlet实现无刷新下拉联动效果
- 在Python程序员面试中被问的最多的10道题
- 一步一步跟我学易语言之初学者的常见问题
- 2019最新的Pycharm激活码(推荐)
- 详解java中float与double的区别