一部が拒否された場合でも、すべての約束が完了するまで待つ 質問する

一部が拒否された場合でも、すべての約束が完了するまで待つ 質問する

ネットワーク リクエストを行っている一連の がありPromise、そのうちの 1 つが失敗するとします。

// http://does-not-exist will throw a TypeError
var arr = [ fetch('index.html'), fetch('http://does-not-exist') ]

Promise.all(arr)
  .then(res => console.log('success', res))
  .catch(err => console.log('error', err)) // This is executed   

どれか 1 つが失敗したかどうかに関係なく、これらすべてが完了するまで待機するとします。リソースにネットワーク エラーが発生する場合がありますが、これはなくてもかまいませんが、発生する可能性がある場合は、続行する前に発生させたいものです。ネットワーク障害を適切に処理する必要があります。

以来Promise.allこれには余地がありません。Promises ライブラリを使用せずにこれを処理するための推奨パターンは何ですか?

ベストアンサー1

アップデートでは、おそらく組み込みのネイティブを使用することをお勧めしますPromise.allSettled:

Promise.allSettled([promise]).then(([result]) => {
   //reach here regardless
   // {status: "fulfilled", value: 33}
});

面白い事実として、以下の回答は、そのメソッドを言語に追加する際における先行技術でした:]


はい、必要なのはreflect:

const reflect = p => p.then(v => ({v, status: "fulfilled" }),
                            e => ({e, status: "rejected" }));

reflect(promise).then((v) => {
    console.log(v.status);
});

または ES5 の場合:

function reflect(promise){
    return promise.then(function(v){ return {v:v, status: "fulfilled" }},
                        function(e){ return {e:e, status: "rejected" }});
}


reflect(promise).then(function(v){
    console.log(v.status);
});

またはあなたの例では:

var arr = [ fetch('index.html'), fetch('http://does-not-exist') ]

Promise.all(arr.map(reflect)).then(function(results){
    var success = results.filter(x => x.status === "fulfilled");
});

おすすめ記事