ES6 Promise.all的使用方法以及其细节详解

ES6 Promise.all用法

Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调。可以将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.all([p1, p2, p3]);

上面代码中,Promise.all方法接受一个数组作为参数,p1、p2、p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。(Promise.all方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。)

p的状态由p1、p2、p3决定,分成两种情况。

  1. 只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
  2. 只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

但是,这里有个需要注意的细节!

如果作为参数的 Promise

实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。

const p1 = new Promise((resolve, reject) => {
  resolve('hello');
})
.then(result => result)
.catch(e => e);

const p2 = new Promise((resolve, reject) => {
  throw new Error('报错了');
})
.then(result => result)
.catch(e => e);

Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了]

上面代码中,p1会resolved,p2首先会rejected,但是p2有自己的catch方法,该方法返回的是一个新的 Promise 实例,p2指向的实际上是这个实例。该实例执行完catch方法后,也会变成resolved,导致Promise.all()方法参数里面的两个实例都会resolved,因此会调用then方法指定的回调函数,而不会调用catch方法指定的回调函数。

如果p2没有自己的catch方法,就会调用Promise.all()的catch方法。

then方法也会把所有异步操作的结果放进一个数组中传给then,就是下面的results。

Promise
.all([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){
    console.log(results);
});

附:promise.all的异步用法

    const promise1 = Promise.resolve(3);
    const promise2 = 42;
    const promise3 = new Promise((resolve, reject) => {
      setTimeout(resolve, 100, 'foo');
    });

    Promise.all([promise1, promise2, promise3]).then((values) => {
      console.log(values);
    });
    // expected output: Array [3, 42, "foo"]

总结

到此这篇关于ES6 Promise.all的使用方法以及其细节的文章就介绍到这了,更多相关ES6 Promise.all使用内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 深入理解Promise.all

    异步之Promise Promise.all Promise.all接收的promise数组是按顺序执行的还是一起执行的,也就是说返回的结果是顺序固定的吗? 目前有两种答案: 应该是同步执行的,但是这样就有效率问题了,如果想改成异步执行怎么办呢? 有些人认为结果是按顺序执行的,有些人认为结果顺序不确定. 那么我们根据实现来解密: 环境为: vscode 1.20.1 node v8.9.0 npm v5.6.0 实验代码: // 获取随机数,toFixed为四舍五入保留小数,0为保留整数,范围-

  • 利用ES6的Promise.all实现至少请求多长时间的实例

    1.背景 我们都知道ajax请求可以加个timeout,就是最多请求多少时间,如果超过这个时间直接就报错. 这个是最多请求多长时间,我现在要做的是,最少要请求多长时间,然后才能执行后续的逻辑. 比如,一个ajax请求 x 毫秒就执行完毕了,但我要让他至少执行1秒钟,那我们会这么想: ajax完成后 , 1. 如果x<1s, 那我们先setTimeout => 1s - x ,然后执行后续操作. 2 如果x>=1s, 那我们直接执行后续操作. 想想这可繁琐了,我们还要在前面记录一下开始时间

  • 字节飞书面试promise.all实现示例

    目录 前言 何为Promise.all? 原生 Promise.all 测试 手动实现Promise.all 测试案例 Promise.race 原生 Promise.race 测试 手写Promise.race 测试案例 Promise.any 原生 Promise.any 测试 手写Promise.any 测试案例 Promise.allSettled 原生 Promise.allSettled 测试 手写 Promise.allSettled 测试案例 结语 参考文章 前言 金三银四,身为

  • 面试手写实现Promise.all

    目录 前言 常见面试手写系列 Promise.resolve 简要回顾 源码实现 Promise.reject 简要回顾 源码实现 Promise.all 简要回顾 源码实现 Promise.allSettled 简要回顾 源码实现 Promise.race 简单回顾 源码实现 结尾 前言 (ಥ﹏ಥ)曾经真实发生在一个朋友身上的真实事件,面试官让他手写一个Promise.all,朋友现场发挥不太好,没有写出来,事后他追问面试官给的模糊评价是基础不够扎实,原理性知识掌握较少... 当然整场面试失利

  • 微信小程序 ES6Promise.all批量上传文件实现代码

    微信小程序 ES6Promise.all批量上传文件实现代码 客户端 Page({ onLoad: function() { wx.chooseImage({ count: 9, success: function({ tempFilePaths }) { var promise = Promise.all(tempFilePaths.map((tempFilePath, index) => { return new Promise(function(resolve, reject) { wx.

  • Promise.all中对于reject的处理方法

    昨天写了个小爬虫,用axios.all同时请求多个页面时,国内网络的原因很容易就超时然后reject了,佛系resolve不可取啊,然后想到可以实现一个"重发失败请求"的功能. Promise.all(requestPromises).then(...).catch(...) 会在所有requestPromises都resolve时才会进then方法,并且把所有结果以一个数组返回.只要有一个失败,就会进catch.如果在单个请求中定义了catch方法,那么就不会进Promise.all

  • ES6 Promise.all的使用方法以及其细节详解

    ES6 Promise.all用法 Promise的all方法提供了并行执行异步操作的能力,并且在所有异步操作执行完后才执行回调.可以将多个 Promise 实例,包装成一个新的 Promise 实例. const p = Promise.all([p1, p2, p3]); 上面代码中,Promise.all方法接受一个数组作为参数,p1.p2.p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理.(P

  • js es6系列教程 - 新的类语法实战选项卡(详解)

    其实es6的面向对象很多原理和机制还是ES5的,只不过把语法改成类似php和java老牌后端语言中的面向对象语法. 一.用es6封装一个基本的类 class Person{ constructor( uName ){ this.userName = uName; } sayName(){ return this.userName; } } 是不是很向php和java中的类, 其实本质还是原型链,我们往下看就知道了 首先说下语法规则: class Person中的Person就是类名,可以自定义

  • 使用AngularJS编写多选按钮选中时触发指定方法的指令代码详解

    最近在做项目时,遇到了需要用到多选按钮选中触发事件的功能,因此我查找了一下AngularJS的提供的指令,但是没有发现相应的指令.而一个看起来很像的指令就是ng-checked,但是这个指令是用来代替标签里面checked属性的,所以也用不了.因此我就自己动手试着写一个这样的指令,相应的代码如下: <form name="test_form" ng-controller="TestCtrl"> <input type="checkbox&

  • python类:class创建、数据方法属性及访问控制详解

    在Python中,可以通过class关键字定义自己的类,然后通过自定义的类对象类创建实例对象. python中创建类 创建一个Student的类,并且实现了这个类的初始化函数"__init__": class Student(object):     count = 0     books = []     def __init__(self, name):         self.name = name 接下来就通过上面的Student类来看看Python中类的相关内容. 类构造和

  • ES6中Array.find()和findIndex()函数的用法详解

    ES6为Array增加了find(),findIndex函数. find()函数用来查找目标元素,找到就返回该元素,找不到返回undefined. findIndex()函数也是查找目标元素,找到就返回元素的位置,找不到就返回-1. 他们的都是一个查找回调函数. [1, 2, 3, 4].find((value, index, arr) => { }) 查找函数有三个参数. value:每一次迭代查找的数组元素. index:每一次迭代查找的数组元素索引. arr:被查找的数组. 例: 1.查找

  • WebStorm ES6 语法支持设置&babel使用及自动编译(详解)

    一.语法支持设置 Preferences > Languages & Frameworks > JavaScript 二.Babel安装 1.全局安装 npm install -g babel-cli 2.当前项目,适用于使用不同babel版本的情况 npm install --save-dev babel-cli 三.Babel基本用法 # 转码结果输出到标准输出 babel example.js # 转码结果写入一个文件 # --out-file 或 -o 参数指定输出文件 bab

  • servlet配置方法及其生命周期详解

    servlet配置: 在web.xml中,首先向服务器注册一个servlet.在<servlet>标签下 给定一个servlet名字,这个servlet-name是我们自己用的,方便我们用它对servlet进行配置. 1 <servlet-name>AServlet</servlet-name>然后指定一个全类名,这个是给服务器使用,服务器用来创建全类名对象的实例 1 <servlet-class>com.servlet.AServlet</servl

  • Java使用agent实现main方法之前的实例详解

    Java使用agent实现main方法之前的实例详解 创建Agent项目 PreMainExecutor 类,在main方法之前执行此方法 public class PreMainExecutor { public static void premain(String agentOps, Instrumentation inst){ System.out.println("premain execute.........."); } } META-INF/MANIFEST.MF Man

  • 类似Object监视器方法的Condition接口(详解)

    在<基于线程.并发的基本概念(详解)>中,我们利用synchronized关键字.Queue队列.以及Object监视器方法实现了生产者消费者,介绍了有关线程的一些基本概念.Object类提供的wait的方法和notifyAll方法,与之对应的是Condition接口提供是await和signalAll.await(或wait)是让当前线程进入等待状态并释放锁,signalAll(或notifyAll)则是唤醒等待中的线程,使得等待中的线程有竞争锁的资格,注意只是资格,并不代表被唤醒的线程就一

  • Android Canvas方法总结最全面详解API(小结)

    本篇文章主要介绍了Android Canvas方法总结最全面详解API,分享给大家,具体如下: 常用方法 drawXxx方法族:以一定的坐标值在当前画图区域画图,另外图层会叠加, 即后面绘画的图层会覆盖前面绘画的图层. clipXXX方法族:在当前的画图区域裁剪(clip)出一个新的画图区域,这个 画图区域就是canvas对象的当前画图区域了.比如:clipRect(new Rect()), 那么该矩形区域就是canvas的当前画图区域 getXxx方法族:获得与Canvas相关一些值,比如宽高

随机推荐