ブログblog

非同期処理について

Writer: tokuyasu 更新日:2023/10/13

こんにちは、デジナーレ福岡オフィスの徳安です。
この記事では、非同期処理について説明します。



スレッド

スレッドとは、プログラムの開始から
処理までの一連の処理の流れのこと。
JavaScriptはコードが1行ずつ実行されて行く。
処理の開始から終了までを、
1つの糸のようにあらわすことができることを
「1つのスレッドでコードが実行されている」と表現される。
前の処理が完了してから次の処理が実行されること

シングルスレッドと呼ぶ。

複数の処理を別々のスレッドに分けて
同時に実行することを 
    マルチスレッドと呼ぶ。
(並列処理と呼ばれる)

同期処理と非同期処理

同期処理とは、ひとつのスレッドで、
前の処理の完了を待ってから次の処理を実行すること。

非同期処理とは、スレッドから一時的に切り離された処理のこと。
(setTimeoutに渡すコールバック関数、promiseなど)

イベントループについて

実行コンテキスト

JavaScriptエンジンによって準備されるコードの実行環境のこと。
コードが実行される際に必ず実行コンテキストが生成される。

コールスタック(実行コンテキストスタック)

実行コンテキストが積み重なってできたものを
「コールスタック」と呼ぶ。
このような処理の仕組みをLIFOと呼ぶ。
(ラストインファーストアウト、最後に入れたものを最初に取り出す。)

イベントループ

コールスタックにコンテキストが積まれているのか定期的に監視し、
コンテキストが積まれていない場合、キューに通知する。

タスクキュー

実行待ちのタスクが格納されるキューのこと
(キューとはデータの出し入れをリスト形式で管理するデータ構造のことを指す)
非同期処理の実行順を管理し、
キューに入った順番で処理を行う。
このような処理の仕組みをFIFOと呼ぶ。
(ファーストインファーストアウト、最初に入れたものを最初に取り出す。)

イベントループから通知を受けると、
コールスタックにタスクを渡す



 

上記の動画の状態を図にして説明↓

・ボタンクリックイベントA
(UIイベントスクリプトが実行された際に、連打した状態を想定)
・関数B 
(関数内にsetTimeout()C と
 5秒間メインスレッドを占領する処理D が存在する)
・setTimeout()C
(4秒間待機する処理を持つ)
・5秒間メインスレッドを占領する処理D 
(1秒間に1回ループする処理を5回繰り返す、while文を記述)

スクリプトが実行された際に、
グローバルコンテキストが生成され、
コールスタックに処理が詰まれる

コールスタック内に積まれた処理が順番に実行される。

関数Bが実行され、メインスレッドを5秒間占領する処理が
実行された後に、コールスタックから削除される。
ボタンクリックイベントAと setTimeout() cは非同期処理のため、
メインスレッドから処理が切り離される

タスクキューに非同期処理が積まれ
実行待ちの状態で待機
(ボタンクリックイベントが、
setTimeout()が実行される前に、積まれた場合を想定)



イベントループは、コールスタックに
コンテキストが積まれているのか定期的に監視し、
コールスタックが空になった際にタスクキューに通知する。

タスクキューはイベントループから通知を受けると、
コールスタックにキューに入った順番でタスクを渡す

コールスタックで処理が実行される。

このような流れで処理が行われる。

ここまで読み進めていただきありがとうございます。