どうも!chuckです。
前回、JavaScriptのスキル判定をしたところ、初心者以上中級者未満だったことが判明しました。
そろそろ中級者だと思っていたのに…(´;ω;`)
なのでフォローアップのために、これから少しずつ知識を補っていきます。
今回は第一弾として、JavaScriptがシングルスレッドであることについて、調べましたのでメモ。
そもそもシングルスレッドって?
シングルスレッドとは、プログラムの処理が単一に行われることです。それに対して、マルチスレッドというものもありまして、こちらは同時にいくつもの処理が行われます。
結城浩さんというJava界隈の方の、小人の例えがわかり易かったです。
シングルスレッドとは1つの道の上を小人が歩くようなもので、マルチスレッドとは道が複数あってそれぞれの道の上を小人が一人ずつ歩いているような感じだそう。わかりやすい!
ちなみに、同期通信・非同期通信という仕組みもありますが、初心者のうちは≒だと思っていいのかな??
そしてJSはシングルスレッド
JavaScriptはシングルスレッドなんですって!びっくりしました。いわば1つの道の上を、1頭のサイがのしのし歩いている感じですね!
Javaを勉強したときにシングルスレッド・マルチスレッドについて学んだのですが、JavaScriptにもその概念があるとは思っても見なかったです。
めっちゃわかりやすい解説↓
以下の2点がエッセンスらしい。
- 関数単位で順番に実行されていく
- 非同期処理は、実行の準備ができたコールバック関数が待ち行列をつくり、現在実行中の関数の処理が終了してから、順に関数が実行されていく
あと、JavaScriptはシングルスレッドではあるんだけど、非同期処理が実行可能とのこと。ややこしいですね(;´Д`)
要は、処理の順番はシャッフルできるけど、実行は1つずつってことだよね。
シングルスレッドだと何が問題なのか
シングルスレッドであることをしっかり理解していないと、setTimeoutやsetIntervalの結果が意図せぬものになってしまうかも。とのこと。
これ僕すっかり誤解してた。timeout系の関数って、指定したミリ秒後に実行されると思ってました。
実際には、指定したミリ秒後に実行キューに登録されるとのこと。つまり、通常はその場で「これ実行しといて」と関数を実行させるところ、ちょっと待ってから「これ実行しといて」という指令が発行されるらしい。
だから、時間のかかる重たい処理に割り込まれると、指令がきちんと時間どおり処理されないこともあるとか。
なるほど…。
setTimeoutに限定したわかりやすいQiitaのページ
ユーザビリティと絡めたお話
シングルスレッドだからこそ、重たい処理による「待ち状態」をなんとかしないとね!というお話。ページのレンダリングが目に見えて遅れてしまったら、ユーザビリティを大きく損なってしまいますよね。
そこで役に立つのが、setTimeout関数らしい。setTimeout(function(){ }, 0 ) と書くだけで、擬似的に並列処理ができるとのこと。
setTimeout以外には、イベントやコールバックでもOKなので、XMLHttpRequestやイベントハンドラでも同様のことが実現できるらしい。
まとめ
僕は業務やプライベートでたまにsetTimeout系を使います。たしかに意図しない挙動をしてくれないことがあり、不思議に思っていました。
ひょっとしたら、今回学んだことへとの理解不足が原因だったのかもしれません。setTimeout系の関数について、シングルスレッドであることを土台にようやく理解・整理することができました。
課題
今回の件でググっていると、WebWorkerという単語をよく目にした。バックグラウンドでJavaScriptを実行できる仕組みらしい。
また次回調べてみようと思います。