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(マクロタスク)キュー:
setTimeoutsetInterval-
setImmediate(Node.js) requestAnimationFrameUIイベント
→ 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