Promise.all()

Метод Promise.all() повертає єдиний проміс, який виконується, коли усі проміси, передані у вигляді ітерабельного об'єкта, були виконані, або коли ітерабельний об'єкт не містить жодного проміса. Він відхиляється з причиною першого відхиленого проміса.

Зазвичай використовується після того, як були запущені асинхронні задачі, що виконуються конкурентно, та були створені проміси для їхніх результатів, щоб мати змогу зачекати, доки усі задачі не будуть виконані.

Синтаксис

Promise.all(iterable);

Параметри

iterable
Ітерабельний об'єкт, такий як Array.

Значення, що повертається

  • Вже вирішений проміс, якщо переданий ітерабельний об'єкт є порожнім.
  • Асинхронно вирішений проміс, якщо переданий ітерабельний об'єкт не містить промісів. Зауважте, що Google Chrome 58 у цьому випадку повертає вже вирішений проміс.
  • Проміс у стані очікування у всіх інших випадках. Цей повернений проміс далі вирішується/відхиляється асинхронно (як тільки стек стане порожнім), коли усі проміси у переданому ітерабельному об'єкті будуть вирішені, або якщо будь-який з промісів буде відхилено. Дивіться приклад щодо "Асинхронності або синхронності Promise.all" нижче. Повернені значення будуть розташовані у порядку, в якому були передані проміси, незалежно від порядку завершення.

Опис

Цей метод може бути корисним для збирання результатів множини промісів.

Виконання

Повернений проміс виконується з масивом, що містить усі значення ітерабельного об'єкта, переданого в якості аргумента (також значення, що не є промісами).

  • Якщо був переданий порожній ітерабельний об'єкт, тоді цей метод вертає (синхронно) вже вирішений проміс.
  • Якщо усі передані проміси виконуються, або це не проміси, проміс, повернений Promise.all, виконується асинхронно.

Відхилення

Якщо будь-який з переданих промісів відхиляється, Promise.all асинхронно відхиляється зі значенням відхиленого проміса, незалежно від того, чи були вирішені інші проміси.

Приклади

Використання Promise.all

Promise.all чекає на усі виконання (або на перше відхилення).

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

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

Якщо ітерабельний об'єкт містить значення, що не є промісами, вони будуть проігноровані, але все одно міститимуться у поверненому масиві проміса (якщо проміс виконається):

// рахуватиметься, ніби передано порожній ітерабельний об'єкт, отже, він виконається
var p = Promise.all([1,2,3]);
// рахуватиметься, ніби переданий ітерабельний об'єкт містить лише вирішений проміс зі значенням "444", отже, він виконається
var p2 = Promise.all([1,2,3, Promise.resolve(444)]);
// рахуватиметься, ніби переданий ітерабельний об'єкт містить лише відхилений проміс зі значенням "555", отже, він буде відхилений
var p3 = Promise.all([1,2,3, Promise.reject(555)]);

// використовуючи setTimeout, ми можемо виконати код після того, як стек стане порожнім
setTimeout(function() {
    console.log(p);
    console.log(p2);
    console.log(p3);
});

// виводить
// Promise { <state>: "fulfilled", <value>: Array[3] }
// Promise { <state>: "fulfilled", <value>: Array[4] }
// Promise { <state>: "rejected", <reason>: 555 }

Асинхронність або синхронність Promise.all

Наступний приклад демонструє асинхронність (або синхронність, якщо передано порожній ітерабельний об'єктPromise.all:

// ми передаємо в якості аргумента масив вже вирішених промісів,
// щоб запустити Promise.all якомога швидше
var resolvedPromisesArray = [Promise.resolve(33), Promise.resolve(44)];

var p = Promise.all(resolvedPromisesArray);
// негайно виводимо значення p
console.log(p);

// використовуючи setTimeout, ми можемо виконати код після того, як стек стане порожнім
setTimeout(function() {
    console.log('стек тепер порожній');
    console.log(p);
});

// виводить, в порядку:
// Promise { <state>: "pending" } 
// стек тепер порожній
// Promise { <state>: "fulfilled", <value>: Array[2] }

Те саме відбувається, якщо Promise.all відхиляється:

var mixedPromisesArray = [Promise.resolve(33), Promise.reject(44)];
var p = Promise.all(mixedPromisesArray);
console.log(p);
setTimeout(function() {
    console.log('стек тепер порожній');
    console.log(p);
});

// виводить
// Promise { <state>: "pending" } 
// стек тепер порожній
// Promise { <state>: "rejected", <reason>: 44 }

Promise.all вирішується синхронно лише тоді, коли переданий ітерабельний об'єкт є порожнім:

var p = Promise.all([]); // буде негайно вирішений
// значення, що не є промісами, будуть проігноровані, але обчислення відбуватиметься асинхронно
var p2 = Promise.all([1337, "привіт"]);
console.log(p);
console.log(p2)
setTimeout(function() {
    console.log('стек тепер порожній');
    console.log(p2);
});

// виводить
// Promise { <state>: "fulfilled", <value>: Array[0] }
// Promise { <state>: "pending" }
// стек тепер порожній
// Promise { <state>: "fulfilled", <value>: Array[2] }

Швидке відхилення у Promise.all

Promise.all відхиляється, якщо будь-який з його елементів було відхилено. Наприклад, якщо ви передаєте чотири проміси, які вирішуються після затримки, та один проміс, який негайно відхиляється, тоді Promise.all буде негайно відхилено.

var p1 = new Promise((resolve, reject) => { 
  setTimeout(() => resolve('один'), 1000); 
}); 
var p2 = new Promise((resolve, reject) => { 
  setTimeout(() => resolve('два'), 2000); 
});
var p3 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('три'), 3000);
});
var p4 = new Promise((resolve, reject) => {
  setTimeout(() => resolve('чотири'), 4000);
});
var p5 = new Promise((resolve, reject) => {
  reject(new Error('відхилено'));
});


// Використовуємо .catch:
Promise.all([p1, p2, p3, p4, p5])
.then(values => { 
  console.log(values);
})
.catch(error => { 
  console.error(error.message)
});

//Виведе: 
//"відхилено"

Цю поведінку можливо змінити, обробивши можливі відхилення:

var p1 = new Promise((resolve, reject) => { 
  setTimeout(() => resolve('p1_відкладене_вирішення'), 1000); 
}); 

var p2 = new Promise((resolve, reject) => {
  reject(new Error('p2_негайне_відхилення'));
});

Promise.all([
  p1.catch(error => { return error }),
  p2.catch(error => { return error }),
]).then(values => { 
  console.log(values[0]) // "p1_відкладене_вирішення"
  console.error(values[1]) // "Error: p2_негайне_відхилення"
})

Специфікації

Специфікація
ECMAScript Latest Draft (ECMA-262)
The definition of 'Promise.all' in that specification.

Сумісність з веб-переглядачами

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome for AndroidFirefox for AndroidOpera for AndroidSafari on iOSSamsung InternetNode.js
all()Chrome Full support 32Edge Full support 12Firefox Full support 29IE No support NoOpera Full support 19Safari Full support 8WebView Android Full support 4.4.3Chrome Android Full support 32Firefox Android Full support 29Opera Android Full support 19Safari iOS Full support 8Samsung Internet Android Full support 2.0nodejs Full support 0.12

Legend

Full support  
Full support
No support  
No support

Див. також