非常教程

JavaScript参考手册

Promise

Promise.all

Promise.all() 方法返回一个Promise, 在可迭代(iterable)参数中所有的 promises 都已经解决了或者当iterable参数不包含 promise 时, 返回解决。或者返回拒绝, 当传递的 promise 包含一个拒绝(reject)时。

语法

Promise.all(iterable);

迭代(iterable)一个可迭代的对象(如ArrayorString)。

返回值

  • An already resolved Promise 如果传递空的可迭代对象

  • An asynchronously resolved Promise 如果传递可迭代对象中不包含Promise. 比如, Google Chrome 58 返回一个 already resolved promise .

  • pending Promise 在其他范例中. 返回的 promise 将会 处于异步等待 resolved/rejected的状态 (as soon as the stack is empty) 当可迭代对象中包含的所有Promise被resolved时, 或者其中任何一个Promise被reject时, 异步等待结束. See the example about "Asynchronicity or synchronicity of Promise.all" below.

描述

这个方法可以用来汇总多个promise的结果。

执行结果:

如果一个空的iterable被传递,那么这个方法返回(同步)一个已经解决的promise。

Promise.all()会异步执行,它的返回值是所有已经执行完毕的Promise,还有尚未执行的Promise.

在所有情况下,返回的promise都是通过一个数组实现的,该数组包含作为参数传递的所有 iterable的值(也是非promise值)。

拒绝:

如果任何Promise被reject,Promise.all会拒绝那些被拒绝的Promise,不论其他promise是否已经解决。

示例

使用Promise.all

Promise.all 等待所有代码的完成(或第一个代码的失败)。

var p1 = Promise.resolve(3);
var p2 = 1337;
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
}); 

Promise.all([p1, p2, p3]).then(values => { 
  console.log(values); // [3, 1337, "foo"] 
});

如果iterable包含非promise值,则它们将被忽略,但仍然计入返回的promise数组值(如果promise已满足):

// this will be counted as if the iterable passed is empty, so it gets fulfilled
var p = Promise.all([1,2,3]);
// this will be counted as if the iterable passed contains only the resolved promise with value "444", so it gets fulfilled
var p2 = Promise.all([1,2,3, Promise.resolve(444)]);
// this will be counted as if the iterable passed contains only the rejected promise with value "555", so it gets rejected
var p3 = Promise.all([1,2,3, Promise.reject(555)]);

// using setTimeout we can execute code after the stack is empty
setTimeout(function(){
    console.log(p);
    console.log(p2);
    console.log(p3);
});

// logs
// Promise { <state>: "fulfilled", <value>: Array[3] }
// Promise { <state>: "fulfilled", <value>: Array[4] }
// Promise { <state>: "rejected", <reason>: 555 }

Promise.all的同步和异步

下面的示例展示了Promise.all的异步(当传递的可迭代对象是空时,是同步的):

// we are passing as argument an array of promises that are already resolved,
// to trigger Promise.all as soon as possible
var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)];

var p = Promise.all(resolvedPromisesArray);
// immediately logging the value of p
console.log(p);

// using setTimeout we can execute code after the stack is empty
setTimeout(function(){
    console.log('the stack is now empty');
    console.log(p);
});

// logs, in order:
// Promise { <state>: "pending" } 
// the stack is now empty
// Promise { <state>: "fulfilled", <value>: Array[2] }

如果Promise.all reject时会出现同样的结果:

var mixedPromisesArray = [Promise.resolve(33), Promise.reject(44)];
var p = Promise.all(mixedPromisesArray);
console.log(p);
setTimeout(function(){
    console.log('the stack is now empty');
    console.log(p);
});

// logs
// Promise { <state>: "pending" } 
// the stack is now empty
// Promise { <state>: "rejected", <reason>: 44 }

但是,当且只当传递的可迭代对象为空时,Promise.all会变成同步执行

var p = Promise.all([]); // will be immediately resolved
var p2 = Promise.all([1337, "hi"]); // non-promise values will be ignored, but the evaluation will be done asynchronously
console.log(p);
console.log(p2)
setTimeout(function(){
    console.log('the stack is now empty');
    console.log(p2);
});

// logs
// Promise { <state>: "fulfilled", <value>: Array[0] }
// Promise { <state>: "pending" }
// the stack is now empty
// Promise { <state>: "fulfilled", <value>: Array[2] }

Promise.all 快速失败行为

如果任意一个元素是rejected,那么Promise.all就是rejected。例如,如果你传递了五个参数,其中四个是经过一定时间间隔后执行resolve,另外一个立刻执行reject,那么Promise.all将会立刻执行reject。

var p1 = new Promise((resolve, reject) => { 
  setTimeout(resolve, 1000, 'one'); 
}); 
var p2 = new Promise((resolve, reject) => { 
  setTimeout(resolve, 2000, 'two'); 
});
var p3 = new Promise((resolve, reject) => {
  setTimeout(resolve, 3000, 'three');
});
var p4 = new Promise((resolve, reject) => {
  setTimeout(resolve, 4000, 'four');
});
var p5 = new Promise((resolve, reject) => {
  reject('reject');
});

Promise.all([p1, p2, p3, p4, p5]).then(values => { 
  console.log(values);
}, reason => {
  console.log(reason)
});

//From console:
//"reject"

//You can also use .catch
Promise.all([p1, p2, p3, p4, p5]).then(values => { 
  console.log(values);
}).catch(reason => { 
  console.log(reason)
});

//From console: 
//"reject"

规范

Specification

Status

Comment

ECMAScript 2015 (6th Edition, ECMA-262)The definition of 'Promise.all' in that specification.

Standard

Initial definition in an ECMA standard.

ECMAScript Latest Draft (ECMA-262)The definition of 'Promise.all' in that specification.

Draft

浏览器兼容性

Feature

Chrome

Edge

Firefox

Internet Explorer

Opera

Safari

Basic Support

32.0

(Yes)

29.0

No

19

7.1

Feature

Android

Chrome for Android

Edge mobile

Firefox for Android

IE mobile

Opera Android

iOS Safari

Basic Support

4.4.4

32.0

(Yes)

29

No

(Yes)

8.0

JavaScript

JavaScript 是一种高级编程语言,通过解释执行,是一门动态类型,面向对象(基于原型)的解释型语言。它已经由ECMA(欧洲电脑制造商协会)通过 ECMAScript 实现语言的标准化。它被世界上的绝大多数网站所使用,也被世界主流浏览器( Chrome、IE、FireFox、Safari、Opera )支持。JavaScript 是一门基于原型、函数先行的语言,是一门多范式的语言,它支持面向对象编程,命令式编程,以及函数式编程。它提供语法来操控文本、数组、日期以及正则表达式等,不支持 I/O,比如网络