JavaScriptの非同期処理についてざっくりまとめ
非同期処理とは
簡単にいうと「裏で行われる処理」のこと。
あるタスクが完了するまで待たずに他の処理を続けることができ、通信やファイルの読み書きなど、時間がかかる処理は非同期に扱われます。
なにが良いのか
例えば、Webサーバーとして使われているNode.jsが、あるクライアントと通信するとき、その通信が同期的(ブロッキング)なものだとWebサーバーの動作が停止してしまいます。
そこで非同期処理が使われ、通信処理が非同期(ノンブロッキングなもの)になると、あるクライアントと通信をしていてもプログラムは停止せず、別のクライアントととも通信を行うことが可能となり、アプリケーションの性能が向上します。
同期的処理の例
JavaScript/TypeScriptではシングルスレッドモデルが採用されているため、プログラムの複数箇所が並列に実行されることはありません。
const name = 'Miriam'; // ①
const greeting = `Hello, my name is ${name}!`; // ②
console.log(greeting); // ③
// "Hello, my name is Miriam!"
MDNより引用
https://developer.mozilla.org/ja/docs/Learn/JavaScript/Asynchronous/Introducing
上記のコードは同期的なプログラムであり、上から①→②→③の順に実行され、次の行に進む前にその行の処理が終わるまで待ちます。
非同期処理の例
非同期処理の簡単な例として、setTimeout
関数を使ってみます。
setTimeout(() => {
console.log('タイマーが呼び出されました')
}, 5000)
console.log('タイマーをセット')
setTimeout
関数の第一引数にはconsole.log()
を実行するだけのコールバック関数を、第二引数にはタイマーが起動するまでのミリ秒数を指定しています。
今回の例では、まず「タイマーをセット」という文字列がコンソールに出力され、5秒後に「タイマーが呼び出されました」という文字列が出力されます。
もしこれが同期的なプログラムであれば、5秒間プログラムが停止してしまうのですが、setTimeout
は非同期的に処理をしてくれるため、setTimeoute
自体は「5秒間待つ」という処理を開始するだけで一瞬で終わり、次の処理に進みます。
プログラムの最後まで到達してもまだ非同期処理が残っているため、プログラム自体は終了せず、5秒経つとsetTimeout
に渡されたコールバックが実行され、ようやくプロセスが終了します。
同期処理と非同期処理の順序
一つ注意したいのが、同期的な処理が行われている間、非同期な処理が割り込まれることはない
ということです。
先程の非同期処理の例だと、setTimeoutのタイマーがあとに続く同期的な処理の途中で完了したとしても、コールバック関数が割り込んで実行されることはなく、最後までプログラムが実行されたあとにsetTimeoutのコールバック関数が実行されます。
おわりに
非同期処理を理解し扱うことは、アプリケーションのパフォーマンスやUXにも大きく関わってくると思うので、このあたりをしっかり頭に入れて開発に取り組んでいきたいですね。
参考
Discussion