0
0

More than 3 years have passed since last update.

【JavaScript】非同期処理とコールバック関数をセットで理解したい

Posted at

タイトル通り!

ただのメモ用かもしれないので雑な内容です。

JavaScriptの基礎

JavaScriptはシングルスレッドで動く言語。つまり並行処理できないということ。

同期処理であろうと非同期処理であろうと2つ以上の処理を同時に行うことはできない。キューに登録された関数が順番に1つずつ実行される。キューに登録される順番が順序通りであることを同期処理、そうとは限らないものを非同期処理という。JavaScript以外(DBなど)に処理を任せている間は、その処理の完了を待たずに次へ進めるため非同期という。

sample1.js
console.log('いち');
console.log('にー');
console.log('さん');
$ node sample1.js
> いち
> にー
> さん
sample2.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秒なので順序通りに出力されるかと思いきや、そうはならない。

sample3.js
setTimeout(function(){console.log('いち')}, 0);
console.log('にー');
console.log('さん');
node sample3.js
> にー
> さん
> いち

これは、上から順にキューが登録されたと同時にコールバック関数のconsole.log('いち');が非同期処理されたため、JavaScriptはsetTimeoutのタイマーに処理を任せている間に次の処理を進めたということになる。

参考文献
JavaScriptの同期、非同期、コールバック、プロミス辺りを整理してみる

非同期の例

非同期ではコードが記述通りの順序で処理されない。

test.js
setTimeout(function() {
    console.log('ハロー');
}, 3000);
console.log('ワールド');

アロー関数で省略表記して、

test.js
setTimeout(() => console.log('ハロー'), 1000);
console.log('ワールド');

nodeコマンドで実行すると、

$ node test.js
> ワールド    // 直後に出力される
> ハロー    // 1秒後に出力される

リクエストのタイミングと順序は、

  1. 「1秒後に"ハロー"の出力」をリクエスト
  2. 「"ワールド"の出力」をリクエスト

このように1行目をリクエストしたらすかさず2行目に進んでいる。本来なら先にリクエストされた処理が完了するまで次の行に進まないが、

Promiseオブジェクトとthenメソッド

Promiseはthen()を使うことでコールバックのような処理が可能。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0