タイトル通り!
ただのメモ用かもしれないので雑な内容です。
JavaScriptの基礎
JavaScriptはシングルスレッドで動く言語。つまり並行処理できないということ。
同期処理であろうと非同期処理であろうと2つ以上の処理を同時に行うことはできない。キューに登録された関数が順番に1つずつ実行される。キューに登録される順番が順序通りであることを同期処理、そうとは限らないものを非同期処理という。JavaScript以外(DBなど)に処理を任せている間は、その処理の完了を待たずに次へ進めるため非同期という。
console.log('いち');
console.log('にー');
console.log('さん');
$ node sample1.js
> いち
> にー
> さん
setTimeout(function(){console.log('いち')}, 1000);
console.log('にー');
console.log('さん');
最初にキューに登録されるのはsetTimeout()
で、その中身のいち
は1秒後のタイマーの結果として出力される。
次にキューに登録されるのは'にー'、最後が'さん'なので、出力結果は下の様になる。
$ node sample2.js
> にー
> さん
> いち
ここではsetTimeout()
の引数としてconsole.log()
を渡し、setTimeout()
からconsole.log()
を呼び出している。このように、関数Aに関数B処理をコールバック関数という。
あ
setTimeout()
のタイマーを0に設定したら、待ち時間0秒なので順序通りに出力されるかと思いきや、そうはならない。
setTimeout(function(){console.log('いち')}, 0);
console.log('にー');
console.log('さん');
node sample3.js
> にー
> さん
> いち
これは、上から順にキューが登録されたと同時にコールバック関数のconsole.log('いち');
が非同期処理されたため、JavaScriptはsetTimeout
のタイマーに処理を任せている間に次の処理を進めたということになる。
非同期の例
非同期ではコードが記述通りの順序で処理されない。
setTimeout(function() {
console.log('ハロー');
}, 3000);
console.log('ワールド');
アロー関数で省略表記して、
setTimeout(() => console.log('ハロー'), 1000);
console.log('ワールド');
node
コマンドで実行すると、
$ node test.js
> ワールド // 直後に出力される
> ハロー // 1秒後に出力される
リクエストのタイミングと順序は、
- 「1秒後に"ハロー"の出力」をリクエスト
- 「"ワールド"の出力」をリクエスト
このように1行目をリクエストしたらすかさず2行目に進んでいる。本来なら先にリクエストされた処理が完了するまで次の行に進まないが、
Promiseオブジェクトとthenメソッド
Promiseはthen()を使うことでコールバックのような処理が可能。