自分用のメモ。
呼び出される順
const a = new Promise(function (resolve, reject) {
console.log("a");
});
const b = new Promise(function (resolve, reject) {
console.log("b");
});
const c = new Promise(function (resolve, reject) {
console.log("c");
});
Promise.all([a, b, c]).then(function (value) {
console.log(value); //呼ばれない
});
------出力結果-------
a
b
c
aが1番目、bが2番目、cが3番目に呼ばれる。- ただし、
a,b,cともに全て非同期処理なので、aが1番目に終わるとは限らない。(この場合はどれも軽い処理なので絶対にaが1番に終わる) resolveは呼ばれていないので、Promise.allのコールバックも呼ばれない。
コールバックの引数の順番
すべてresolve
const a = new Promise((resolve, reject) => {
console.log("a");
setTimeout(resolve, 3000, "aが終わった");
});
const b = new Promise((resolve, reject) => {
console.log("b");
setTimeout(resolve, 2000, "bが終わった");
});
const c = new Promise((resolve, reject) => {
console.log("c");
setTimeout(resolve, 1000, "cが終わった");
});
Promise.all([a, b, c]).then((values) => {
console.log(values); //呼ばれる
});
------出力結果-------
a
b
c
["aが終わった","bが終わった","cが終わった"]
a,b,cの全てでresolveが呼ばれているので、Promise.allのコールバックも呼ばれる。- コールバックに入ってくる
resolveの引数は、呼び出した順になる。
(この場合、一番最初に処理が終わるのはcだが、["cが終わった","bが終わった","aが終わった"]という順番にはならずに、a→b→cという呼び出し順である["aが終わった","bが終わった","cが終わった"]になる)
1つだけreject
const a = new Promise((resolve, reject) => {
console.log("a");
setTimeout(resolve, 3000, "aが終わった");
});
const b = new Promise((resolve, reject) => {
console.log("b");
setTimeout(reject, 2000, "bが終わった");
});
const c = new Promise((resolve, reject) => {
console.log("c");
setTimeout(resolve, 1000, "cが終わった");
});
Promise.all([a, b, c])
.then((values) => {
console.log(values); //呼ばれない
})
.catch((err) => {
console.log(err); //呼ばれる
});
Promise.allは「渡したすべてのPromiseがreloveされたらコールバックを実行する」という関数なので、この場合はbでrejectを呼んでいるので、コールバックは呼ばれない。その代わりにcatch文の部分が呼ばれる。- また、
Promise.allは「渡した全てのpromiseがresolveされるまで待つけど、どれか1つでもrejectされたらrejectする」という性質もある。- なので「aはresolveされたけど、b,cは実行中」という場合に、bがrejectされた場合は、cの処理を途中でストップする
- 逆に「結果に関わらず、a,b,cのすべてを最後まで実行したい!」という場合は、
Promise.allSettledを使う。
おわり
関連:Promise.allSettled、Promise.all、Promise.any、Promise.raceの違い
コメント