1. ホーム
  2. ジャバスクリプト

[解決済み】Promise.all: 解決された値の順序

2022-04-21 15:59:59

質問

見る MDN のように見えます。 values に渡される then() のコールバックには、Promise.allの順序で値が含まれています。例えば

var somePromises = [1, 2, 3, 4, 5].map(Promise.resolve);
return Promise.all(somePromises).then(function(results) {
  console.log(results) //  is [1, 2, 3, 4, 5] the guaranteed result?
});

どなたか、どのような順序で記述された仕様書を引用していただけませんか? values を入れるべきでしょうか?

PS: このようなコードを実行すると、これが真実であるように思えるのですが、もちろんそれは証拠ではなく、偶然かもしれません。

解決するには?

手短に言うと 順番は守られる .

リンク先の仕様に従うと Promise.all(iterable) を取る。 iterable をパラメータとして、内部的に PerformPromiseAll(iterator, constructor, resultCapability) をループさせ、後者は iterable を使って IteratorStep(iterator) .

解決は Promise.all() Resolve ここで、解決された各プロミスは、内部的に [[Index]] スロットがあり、これは元の入力におけるプロミスのインデックスをマークします。


Promise.all()に渡すイテラブルが厳密な順序(例えば配列)であれば、出力は厳密な順序になることを意味します。

以下のフィドル(ES6)で、この動作を確認できます。

// Used to display results
const write = msg => {
  document.body.appendChild(document.createElement('div')).innerHTML = msg;
};

// Different speed async operations
const slow = new Promise(resolve => {
  setTimeout(resolve, 200, 'slow');
});
const instant = 'instant';
const quick = new Promise(resolve => {
  setTimeout(resolve, 50, 'quick');
});

// The order is preserved regardless of what resolved first
Promise.all([slow, instant, quick]).then(responses => {
  responses.map(response => write(response));
});