ホームページ > ウェブフロントエンド > jsチュートリアル > 非同期の詳細: マイクロタスク、マクロタスク、およびイベント ループ

非同期の詳細: マイクロタスク、マクロタスク、およびイベント ループ

Linda Hamilton
リリース: 2025-01-01 08:23:10
オリジナル
1024 人が閲覧しました

Deep Dive in Asynchrony: Microtasks, Macrotasks, and the Event Loop

JavaScript の非同期の性質は、仕組みを詳しく理解するまでは魔法のように感じるかもしれません。秘訣はイベント ループにあり、マイクロタスクマクロタスクという 2 つの主要なプレーヤーを調整します。しかし、それらは何で、どのように機能し、なぜ重要なのでしょうか?この概念をマスターするための詳細、例、ヒントを使って謎を解き明かしましょう。


イベント ループとタスク キュー

JavaScript エンジンは単一スレッドでコードを実行します。非同期操作を処理するには、コール スタックとタスク キューの間で調整を行うイベント ループに依存します。これらのタスク キューは、マイクロタスクマクロタスク の 2 つのカテゴリに分割されます。

マイクロタスク

マイクロタスクは、現在実行中の JavaScript コードが終了し、コール スタックが空になったらすぐに実行する必要がある優先度の高いタスクです。これらにより、迅速なフォローアップ アクションと一貫した状態が保証されます。一般的な例は次のとおりです。

  • 約束 (.then、async/await)
  • MutationObserver コールバック

マクロタスク

マクロタスクは、すべてのマイクロタスクが実行された後にのみイベント ループが処理する優先度の低いタスクです。これらは、より大規模な遅延操作や外部イベントを処理します。一般的な例は次のとおりです。

  • タイマー (setTimeout、setInterval)
  • MessageChannel コールバック
  • I/O 操作

どちらのキューにも含まれない requestAnimationFrame もあります。ブラウザのレンダリング サイクルと同期するため、スムーズなアニメーションに最適です。


仕組み

イベント ループがタスクを処理する方法は次のとおりです。

  1. 最初に同期コードを実行します。
  2. マイクロタスクキューをクリアします。
  3. マクロタスクキューから 1 つのタスクを実行します。
  4. すべてのタスクが処理されるまで、ステップ 2 と 3 を繰り返します。

この優先順位付けにより、Promise などの優先度の高いタスクが、タイマーなどの緊急性の低い操作よりも前に解決されます。


実際の例

以下は、同期コード、マイクロタスク、マクロタスク、および requestAnimationFrame の間の相互作用を示す実用的なコード スニペットです。

console.log('Synchronous code starts');

// Macrotask: setTimeout
setTimeout(() => {
  console.log('Macrotask: setTimeout');
}, 0);

// Macrotask: setInterval
const intervalId = setInterval(() => {
  console.log('Macrotask: setInterval');
  clearInterval(intervalId);
}, 100);

// Microtask: Promise
Promise.resolve().then(() => {
  console.log('Microtask: Promise then 1');
  Promise.resolve().then(() => {
    console.log('Microtask: Promise then 2');
  });
});

// Microtask: MutationObserver
const observer = new MutationObserver(() => {
  console.log('Microtask: MutationObserver');
});
const targetNode = document.createElement('div');
observer.observe(targetNode, { attributes: true });
targetNode.setAttribute('data-test', 'true');

// Macrotask: MessageChannel
const channel = new MessageChannel();
channel.port1.onmessage = () => {
  console.log('Macrotask: MessageChannel');
};
channel.port2.postMessage('Test');

// requestAnimationFrame
requestAnimationFrame(() => {
  console.log('Outside task queues: requestAnimationFrame');
});

console.log('Synchronous code ends');
ログイン後にコピー

期待される出力

出力シーケンスは優先順位を明確にするのに役立ちます:

  1. 同期コード: 「同期コードの開始」、「同期コードの終了」
  2. マイクロタスク:
    • 「マイクロタスク: 約束して 1」
    • 「マイクロタスク: 約束して 2」
    • 「マイクロタスク: MutationObserver」
  3. マクロタスク:
    • 「マクロタスク: setTimeout」
    • 「マクロタスク: MessageChannel」
    • 「マクロタスク: setInterval」
  4. requestAnimationFrame: 「タスクキュー外: requestAnimationFrame」

詳細: マイクロタスクとマクロタスク

マイクロタスク: 主な特徴

  • 同期コードが完了したらすぐに実行します。
  • Promise の解決や DOM の変更への対応など、小規模で優先度の高い更新に最適です。
  • 例: Promise、MutationObserver。

マクロタスク: 主な特徴

  • すべてのマイクロタスクがクリアされた後にのみ実行します。
  • 大規模で優先度の低い操作または外部イベント処理に使用されます。
  • 例: タイマー、MessageChannel。

requestAnimationFrame: The Odd One Out

requestAnimationFrame はタスク キューの一部ではありませんが、非同期では独自の役割を果たします。次のブラウザの再描画前にコードが実行されるようにスケジュールを設定し、フレーム ドロップを最小限に抑え、アニメーションをよりスムーズにします。


結論

マイクロタスク、マクロタスク、およびイベント ループの間の相互作用は、JavaScript の非同期性の中心です。これらの概念を理解して活用することで、より効率的で保守しやすく、パフォーマンスの高いコードを作成できます。覚えておいてください: 最初にマイクロタスク、2 番目にマクロタスク、そして視覚的に磨き​​をかけるために requestAnimationFrame を使用します。コーディングを楽しんでください!

以上が非同期の詳細: マイクロタスク、マクロタスク、およびイベント ループの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート