1
0

Promise と async function の 同期実行される範囲について

Last updated at Posted at 2024-10-01

Promise も async function も 同期実行される範囲があります。

これを実行したらどう実行されるかわかりますでしょうか?

console.log('1');
new Promise(resolve => {
   console.log('2');
   resolve();
});
console.log('3');

これを実行したらどう実行されるかわかりますでしょうか?

console.log('1');
(async function() {
   console.log('2');
})();
console.log('3');

答えは

1
2
3

です。

なぜなら

  • Promise コンストラクタは同期実行されるから
  • async await に於いて、非同期になるのは await されたときから

だからです

とりあえず同期で動いてほしくないならこれでいいです。

console.log('1');
Promise.resolve()
.then(() => console.log('2'));
console.log('3');
1
3
2

これと同等の処理を Promise コンストラクタを使って書くならこうです

console.log('1');
new Promise(resolve => resolve())
.then(() => console.log('2'));
console.log('3');

async function を使って書くならこうなります

console.log('1');
(async function () {
   await Promise.resolve();
   console.log('2');
})();
console.log('3');

これは Promise を使わずに書くならこうなります

console.log('1');
queueMicrotask(() => console.log('2'));
console.log('3');

ちなみに queueMicrotask の polyfill は次の様な実装です、

if (typeof globalThis.queueMicrotask !== "function") {
  globalThis.queueMicrotask = function (callback) {
    Promise.resolve()
      .then(callback)
      .catch((e) =>
        setTimeout(() => {
          throw e;
        }),
      );
  };
}

つまり、 非同期実行してほしい場合は Promise.prototype.then() ……つまり await しろって話です。

以上。

追伸

この実行順序はわかりますよね?

console.log('1');
new Promise(resolve => {
   console.log('2');
   resolve();
})
.then(() => console.log('6'));

console.log('3');

(async function () {
  console.log('4');
  await Promise.resolve();
  console.log('7');
})();

console.log('5');

See the Pen Untitled by juner clarinet (@juner) on CodePen.

参考

1
0
3

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
1
0