[解決済み] 複数のプロミスを並列に待ち、フェイルファストさせない方法は?重複
質問
を使っています。
async
/
await
を複数回発射する
api
を並列に呼び出すことができます。
async function foo(arr) {
const results = await Promise.all(arr.map(v => {
return doAsyncThing(v)
}))
return results
}
とは違って
loops
,
Promise.all
は並列に実行されます。
(つまり、結果待ちの部分は並列に実行されます)。
しかし も知っています。 :
Promise.allは、要素の1つが拒否された場合、そして Promise.allは高速に失敗します。タイムアウト後に解決する4つの約束があったとして タイムアウト後に解決する4つの約束があり、1つがすぐに拒否された場合、Promise.allはすぐに拒否されます。 を即座に拒否します。
これを読むと、もし私が
Promise.all
で5つのプロミスを実行し、最初に終了したプロミスが
reject()
を返すと、他の 4 つは事実上キャンセルされ、その約束された
resolve()
の値は失われます。
3つ目の方法はありますか?実行は事実上並列ですが、1つの失敗で全体が台無しにならないような方法はありますか?
どのように解決するのですか?
ES2020の内容 プロミス.allSettled を含んでおり、これはあなたが望むことを行います。
Promise.allSettled([
Promise.resolve('a'),
Promise.reject('b')
]).then(console.log)
出力します。
[
{
"status": "fulfilled",
"value": "a"
},
{
"status": "rejected",
"reason": "b"
}
]
しかし、もしあなたが自分自身でロール・アップしたいのであれば、quot;roll your own" を使って
Promise#catch
を使うということは、プロミスが解決されるということです(あなたが
catch
から例外を投げるか,手動でプロミスの連鎖を拒否しない限り),解決されたプロミスを明示的に返す必要はないことを意味します.
というわけで、単純にエラー処理を
catch
で処理するだけで、やりたいことが実現できるのです。
もしエラーが結果で見えるようにしたいのであれば、それらを表面化するための規約を決めなければならないことに注意してください。
コレクション内の各プロミスに拒否処理関数を適用するには、以下のようにします。 Array#map を使用し、さらに プロミス.all を使用して、それらすべてが完了するのを待ちます。
例
次のように出力されます。
Elapsed Time Output
0 started...
1s foo completed
1s bar completed
2s bam errored
2s done [
"foo result",
"bar result",
{
"error": "bam"
}
]
async function foo() {
await new Promise((r)=>setTimeout(r,1000))
console.log('foo completed')
return 'foo result'
}
async function bar() {
await new Promise((r)=>setTimeout(r,1000))
console.log('bar completed')
return 'bar result'
}
async function bam() {
try {
await new Promise((_,reject)=>setTimeout(reject,2000))
} catch {
console.log('bam errored')
throw 'bam'
}
}
function handleRejection(p) {
return p.catch((error)=>({
error
}))
}
function waitForAll(...ps) {
console.log('started...')
return Promise.all(ps.map(handleRejection))
}
waitForAll(foo(), bar(), bam()).then(results=>console.log('done', results))
参照 また .
関連
-
[解決済み] ページを再読み込みせずにURLを変更するにはどうすればよいですか?
-
[解決済み] async」と「await」の使い方とタイミング
-
[解決済み] 既存のコールバックAPIをプロミスに変換するにはどうすればよいですか?
-
[解決済み] 複数のnpmスクリプトを並列に実行するにはどうしたらいいですか?
-
[解決済み] async/await関数を並列に呼び出す
-
[解決済み] 複数のタスクにasync/awaitを使用する
-
[解決済み] ExtJS 4のイベントハンドリングについて
-
[解決済み] CORS OriginヘッダーとCSRFトークンによるCSRF保護
-
[解決済み] Javascript / jQueryでAndroid端末を検出する。
-
[解決済み] BlobからArrayBufferへ移行する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] async/await関数を並列に呼び出す
-
[解決済み】一部の約束が拒否されても、すべての約束が完了するまで待つ
-
[解決済み] <Enter>でjQuery UIダイアログを送信する
-
[解決済み] reactのrender関数でdynamic hrefを作成するには?
-
[解決済み] Chart.jsを使ってドーナツチャートの中にテキストを追加するには?
-
[解決済み] node.jsで文字列のsha1ハッシュを取得するにはどうすればよいですか?
-
[解決済み] Javascriptで動的に命名されたメソッドを呼び出すにはどうすればよいですか?
-
[解決済み] jqueryはjavascriptのライブラリなのかフレームワークなのか?[クローズド]
-
[解決済み] JavaScriptで長い配列を小さい配列に分割する方法
-
[解決済み] jQueryのバージョン1、バージョン2、バージョン3の違いは何ですか?[クローズド]