基本的にJavaScriptはシングルスレッドなので同期処理だけです。
非同期を実現する為にイベント駆動を採用しています。
EventEmitterにAの条件を満たしたら、引数のB関数を実行してね。
…というお願いだけしたら、さっさと処理を終了させ待機状態になります。
(ブラウザにはEventのAPIが用意されていますが、Node.jsはそのAPIが無いのでEventEmitterをこしらえて代用しているといった所です)
待機状態ではイベントの監視のみを行います。
イベント達成条件を満たしたらその関数を1個取り上げて超高速処理で完結。
そして必要に応じてイベント登録を行いまた待機状態に戻る。
この流れをイベントループと呼んだりします。
基本的には擬似的な並列処理です。
例えばsetTimeout(fn, 1000)
を実行しても、1,004ミリ秒後という感じで多少発火がずれます。
同期処理やイベントループの巡回などの都合で発火タイミングは多少狂います。
因みにWorker Threadsなどを使って完全な並列処理なんかも作れると思いますが、
そもそもNode.jsでどれだけやるかみたいな話になりそうなので割愛です。
サーバーとの通信の結果(レスポンス)を使う処理をしたい場合、サーバーとの通信とその結果を使った処理を「同期的」にするために、PromiseやAsync&Awaitがあるのでしょうか?
まぁそんな感じですね。
記述を同期に近づけただけで、実体は非同期処理の羅列ですけどね。
ちょっとその辺解説します。
JavaScriptはシングルスレッドです。
一瞬で処理を終了させてイベントループを回さなければなりません。
そもそも同期処理内で待つという思想はなく、sleep
すら存在しません。
サーバーの役割次第ですが、
WebサーバーはChromeなどのブラウザからの通信を「待つ」わけですよね?
「待つ」にはイベント登録が必要不可欠です。
それではコードがイベント登録だらけでかなり読み辛くなってしまいます。
なので「せめてコードだけでも同期的に書きたい」という要望が生まれ、
その要望に合致するのがPromise + async/awaitです。
これらを利用することで、あたかも同期処理っぽくコードが記述できるようになりました。
しかし、結局は非同期処理の向こうに飛ばしているわけで、二度と同期処理には戻ってこれません。