9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Promiseで定義したコールバックの実行順序

Posted at

Promiseを定義したときにasync/awaitするとコードを見たまま上から下に実行されるので難しくないのですが、then/catchで後の処理を定義するとどのタイミングでコールバックが実行されるのかわかっていませんでした。

ちょっと調べてみたのでまとめます。

サンプル

aとbというPromiseを作ってそれぞれの関数の中でログを出力してみます。
また、各定義の間と、aとbをPromise.allした後にもログを出力します。

const a = new Promise((resolve, reject) => {
  console.log('a');
  resolve('a: resolve');
})
  .then(() => { console.log('a: then'); });

console.log('aの後')

const b = new Promise((resolve, reject) => {
  console.log('b');
  resolve('b: resolve');
})
  .then(() => { console.log('b: then'); });

console.log('bの後')

Promise.all([a, b])
  .then(() => { console.log('c: then'); });

console.log('d');

結果は次のようになりました。

[LOG]: "a" 
[LOG]: "aの後" 
[LOG]: "b" 
[LOG]: "bの後" 
[LOG]: "d" 
[LOG]: "a: then" 
[LOG]: "b: then" 
[LOG]: "c: then"

ふむ、thenの中の出力は定義後のdの後に表示されました。

どうしてこうなった

書き慣れてる人はこんな挙動は当然よく見てて知ってると思うのですが、どういう仕様なんでしょう?

これらのページを読んでたら下のように定義されていました。

保証
旧来のコールバック渡しとは異なり、プロミスでは以下のことが保証されています。

  • then() によって追加されたコールバックは、現在の JavaScript イベントループの現在の処理の完了より前には決して呼び出されません。

サンプルに書いたような状況だとdを出力する箇所が完了してからすべてのthenが処理されるという感じですかね。
async/awaitとthen/catchをなんとなくで書き分けないで状況によって書き分けられるようになりたいですねー。

9
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?