両方の非同期操作がトリガーされ、同時に実行する機会が与えられるように、次のコードを変更するにはどうすればよいですか?
const value1 = await getValue1Async();
const value2 = await getValue2Async();
// use both values
このようなことをする必要がありますか?
const p1 = getValue1Async();
const p2 = getValue2Async();
const value1 = await p1;
const value2 = await p2;
// use both values
私はこれがうまくいくと思う:
const [value1, value2] = await Promise.all([getValue1Async(),getValue2Async()]);
理解に役立つ場合のより詳細な例を以下に示します。
const promise1 = async() => {
return 3;
}
const promise2 = async() => {
return 42;
}
const promise3 = async() => {
return 500;
// emulate an error
// throw "something went wrong...";
}
const f1 = async() => {
try {
// returns an array of values
const results = await Promise.all([promise1(), promise2(), promise3()]);
console.log(results);
console.log(results[0]);
console.log(results[1]);
console.log(results[2]);
// assigns values to individual variables through 'array destructuring'
const [value1, value2, value3] = await Promise.all([promise1(), promise2(), promise3()]);
console.log(value1);
console.log(value2);
console.log(value3);
} catch (err) {
console.log("there was an error: " + err);
}
}
f1();
拒否を正しく処理し、未処理の拒否に直面することなくPromises.all()を安全に使用できることを確認してください。 (編集:議論ごとの説明:エラー_unhandled rejection
_ではなく、単にコードで処理されない拒否。Promise.all()
は最初のプロミスの拒否をスローし、ignore残り)。
以下の例では、[[error、results]、...]の配列が返され、結果やエラーの処理を容易にします。
_let myTimeout = (ms, is_ok) =>
new Promise((resolve, reject) =>
setTimeout(_=> is_ok ?
resolve(`ok in ${ms}`) :
reject(`error in ${ms}`),
ms));
let handleRejection = promise => promise
.then((...r) => [null, ...r])
.catch(e => [e]);
(async _=> {
let res = await Promise.all([
myTimeout(100, true),
myTimeout(200, false),
myTimeout(300, true),
myTimeout(400, false)
].map(handleRejection));
console.log(res);
})();
_
ただし、catch()内からスローしてすべての待機を停止する(および残りの結果を破棄する)ことができます-try/catchブロックごとに1回だけ実行できるため、has_thorwnフラグを維持して確認する必要があります未処理のエラーは発生しません。
_let myTimeout = (ms, is_ok) =>
new Promise((resolve, reject) =>
setTimeout(_=> is_ok ?
resolve(`ok in ${ms}`) :
reject(`error in ${ms}`),
ms));
let has_thrown = false;
let handleRejection = promise => promise
.then((...r) => [null, ...r])
.catch(e => {
if (has_thrown) {
console.log('not throwing', e);
} else {
has_thrown = 1;
throw e;
}
});
(async _=> {
try {
let res = await Promise.all([
myTimeout(100, true),
myTimeout(200, false),
myTimeout(300, true),
myTimeout(400, false)
].map(handleRejection));
console.log(res);
} catch(e) {
console.log(e);
}
console.log('we are done');
})();
_
const wait = (ms, data) => new Promise( resolve => setTimeout(resolve, ms, data) )
const reject = (ms, data) => new Promise( (r, reject) => setTimeout(reject, ms, data) )
const e = e => 'err:' + e
const l = l => (console.log(l), l)
;(async function parallel() {
let task1 = reject(500, 'parallelTask1').catch(e).then(l)
let task2 = wait(2500, 'parallelTask2').catch(e).then(l)
let task3 = reject(1500, 'parallelTask3').catch(e).then(l)
console.log('WAITING')
;[task1, task2, task3] = [await task1, await task2, await task3]
console.log('FINISHED', task1, task2, task3)
})()
他の回答で指摘されたように、拒否された約束は未処理の例外を発生させる可能性があります。
この1つ.catch(e => e)
は、エラーをキャッチしてチェーンに渡し、resolve
の代わりにrejecting
への約束を許可する、すてきな小さなトリックです。 。
このES6コードを見つけた場合、見苦しい here 。