JavaScript イベントループの仕組みをGIFアニメで分かりやすく解説
Post on:2019年12月25日
JavaScript イベントループの仕組みについてGIFアニメーションで分かりやすく解説された記事を紹介します。
✨♻️ JavaScript Visualized: Event Loop
by Lydia Hallie
下記は各ポイントを意訳したものです。
※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。
JavaScriptを視覚的に解説: イベントループ
イベントループは、JavaScriptデベロッパーが避けては通れない関門の1つですが、最初は理解しにくいかもしれません。私は視覚学習者なので、GIFアニメで視覚的に説明することで、あなたの手助けをしようと思います。
説明の前に、まずイベントループとは何でしょうか?
なぜ気にする必要があるのでしょうか?
JavaScriptはシングルスレッドで、一度に実行できるタスクは1つだけです。通常は問題ありませんが、30秒かかるタスクを実行していると想像してみてください 、、、そのタスクを実行している間は他が実行するのを30秒待つことになります。JavaScriptはデフォルトでブラウザのメインスレッドで実行されるため、UI全体が動かなくなります😬 反応のないWebサイトは誰も望んでいません。
幸いなことに、ブラウザはJavaScriptエンジン自体で提供されていない機能があります、Web APIです。Web APIにはDOM API, setTimeout, HTTPリクエストなどが含まれ、これらの機能は非同期のノンブロッキングに役立ちます🚀
では、イベントループについて見てましょう。
関数を呼び出すと、コールスタック(call stack)と呼ばれるものに追加されます。コールスタックはJavaScriptエンジンの一部であり、ブラウザ固有ではありません。これはスタック、つまり先入れ先出しします。関数が値を返すと、スタックからポップされます👋
関数は呼び出されたときにコールスタックにプッシュされ、値が返されたときにポップされます。
respond関数は、setTimeout関数を返します。setTimeoutはWeb APIによって提供され、メインスレッドをブロックせずにタスクを遅延させることができます。setTimeout関数に渡したコールバック関数、アロー関数() => { return 'Hey' } がWeb APIに追加されます。その間、setTimeout関数とrespond関数はスタックからポップされ、両方とも値を返します。
setTimeoutはブラウザから提供され、Web APIがコールバックを処理します。
Web APIでは渡された2番目の引数である1000ミリ秒間、タイマーが実行されます。コールバックはすぐにコールスタックに追加されるのではなく、キュー(queue)と呼ばれるものに渡されます。
タイマーが終了すると(この場合は1000ミリ秒)、コールバックはコールバックキューに渡されます。
ここは少し紛らわしいかもしれません!
コールバック関数が1000ミリ秒後にコールスタックに追加される(つまり値を返す)ということではありません。1000ミリ秒後にキューに追加されるだけです。キューなので、関数はその順番を待たなければなりません!
ここは特に注目してください!
イベントループが唯一のタスクを実行する時間です。キューを呼び出し、スタックに接続します。コールスタックが空の場合は以前に呼び出されたすべての関数が値を返し、スタックからポップされた場合はキュー無いの最初のアイテムがコールスタックに追加されます。この場合、他の関数は呼び出されません。つまり、コールバック関数がキューの最初のアイテムになるまでにコールスタックは空になります。
イベントループは、コールバックキューとコールスタックを調べます。コールスタックが空の場合、キュー内の最初のアイテムがスタックにプッシュされます。
コールバックはコールスタックに追加され、呼び出されて値を返し、スタックからポップされます。
コールバックがコールスタックに追加され、実行されます。値を返すと、コールスタックからポップされます。
記事を読むことは勉強になりますが、実際に作業することで理解が深まります。下記のコード実行した場合にコンソールに何が記録されるか確認してみてください。
1 2 3 4 5 6 7 |
const foo = () => console.log("First"); const bar = () => setTimeout(() => console.log("Second"), 500); const baz = () => console.log("Third"); bar(); foo(); baz(); |
どうでしたか?
このコードをブラウザで実行した時に何が起きるかを簡単に見てましょう。
- barを呼び出すと、setTimeout関数が返されます。
- setTimeoutに渡したコールバックがWeb APIに追加され、setTimeout関数とbarがコールスタックからポップされます。
- タイマーが実行され、その間にfooが呼び出され、Firstがログに記録されます。fooがundefined(未定義)を返すと、bazが呼び出され、コールバックがキューに追加されます。
- bazはThirdに記録されます。イベントループはbazが返された後、コールスタックが空であることを確認し、その後コールバックがコールスタックに追加されます。
- コールバックはSecondを記録します。
これでイベントループについて少し簡単になったと思います。もしまだ混乱していても、心配しないでください。最も重要なことは、特定のエラーや動作がどこからくるかを理解し、正しい用語をGoogleで検索し、良質なナレッジコミュニティにたどりつくことです💪🏼
質問があれば、気軽にお問い合わせください。
sponsors