setTimeout(..., 0)
は**「非同期」ですが、「処理を待つわけではなく、イベントループの次のタイミングに回す」**だけなので、完全な意味で「何かの完了を待つ」動作とは違います。
🔄 正確に言うとこうなります:
-
setTimeout(fn, 0)
は、「今やってる同期処理が全部終わった後に、fn
をキューに入れて非同期実行する」仕組みです。 - つまり、「次のタスク(マクロタスク)」として処理されます。
✅ たとえば:
console.log('A');
setTimeout(() => console.log('B'), 0);
console.log('C');
結果は:
A
C
B
✨ だからこう言うと正確:
「
setTimeout(..., 0)
を使うと、今の処理がすべて終わった後に発火できるから、例えば DOM 更新が終わってから何かしたい時や、他のイベント発火後に順番をずらしたい時に使える」
🎯 まとめ
「何かが終わるまで待つ」という意味での「非同期処理」じゃないです。
setTimeout(..., 0)
は「順番をずらしたいだけ」の時に使うテクニックです。✨
では、Microtask
と setTimeout(fn, 0)
の違いは? (2025/04/18テーマ追記)
🧠 結論:どっちが先に実行される?
Promise.resolve().then(() => console.log("microtask"));
setTimeout(() => console.log("macrotask (setTimeout 0)"), 0);
👉 結果は:
microtask
macrotask (setTimeout 0)
🔁 イベントループのおさらい
JavaScript の実行は「イベントループ」という仕組みで行われるんだけど、
そこでキューが2種類登場する:
✔️ Microtask(マイクロタスク)キュー:
-
Promise.then
,catch
,finally
queueMicrotask()
MutationObserver
→ 現在の実行が終わった直後、次の描画前に即実行!
✔️ Macrotask(マクロタスク)キュー:
setTimeout
setInterval
-
setImmediate
(Node.js) requestAnimationFrame
UIイベント
→ 1イベントループの最後に処理される
(次のループまで“後回し”される)
💥 違いを感覚的にいうと
処理 | どのくらい早い? | 実行タイミング |
---|---|---|
Promise.then |
超早い🔥 | 現在のタスクが終わった直後、即 |
setTimeout |
遅め🕗 | 「次のイベントループ」のタイミングで実行 |
🧪 比較コード
console.log("start");
setTimeout(() => {
console.log("setTimeout");
}, 0);
Promise.resolve().then(() => {
console.log("promise");
});
console.log("end");
実行結果:
start
end
promise
setTimeout
✅ いつ使い分ける?
処理内容 | おすすめ | 理由 |
---|---|---|
★UIをブロックしたくない処理 | ★setTimeout | ★イベントループを1周させるのでブロックしない |
軽くてすぐ終わる後処理 | Microtask | すぐに実行される |
🤓 MDN の補足
MDNの Microtask ガイド にもある通り:
マイクロタスクはイベントループの「現在の」ターンの最後にまとめて実行されます。
次の描画やイベントが来る前に全て終わらせる責任があるため、重い処理を入れるとUIが止まる可能性もある。
💡まとめ
-
Promise.then()
は Microtask → 超即実行(優先度高) -
setTimeout(..., 0)
は Macrotask → 次のループで実行(後回し)
だから:
- 素早い後処理・順序制御 →
Promise.then
- イベントループを遅らせたい処理 →
setTimeout