teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

2

全体的に文章を修正

2018/11/16 10:16

投稿

miyabi-sun
miyabi-sun

スコア21465

answer CHANGED
@@ -1,4 +1,4 @@
1
- これがJS名物、非同期プログラミングの洗礼です。
1
+ これがJS名物、非同期処理の洗礼です。
2
2
  Node.jsのイベントループに関して調べましょう。
3
3
 
4
4
  軽く概要だけ説明します。
@@ -7,10 +7,14 @@
7
7
  それでは遅いファイルアクセスやネットワークアクセスの度に全処理を止めてしまいます。
8
8
  そこで、JSはイベント駆動という思想を使って運用しています。
9
9
 
10
- JSにはイベントループ置き場というものがあります。
10
+ JSにはイベント置き場というものがあります。
11
11
  そこに「イベントの発火条件」と「条件を満たした時に実行して欲しい処理を関数化したモノ」を登録します。
12
- JSは既存の処理を全て実行した後、イベントループ状態となり、イベントの発火条件を満たした関数を一つずつ取り出して実行していきます。
13
12
 
13
+ JSは既存の処理を全て実行した後、イベントループ状態となり、
14
+ イベントの発火条件を満たした関数を探して巡回するだけのモードに突入します。
15
+ そして、発火条件を満たしたイベントがあれば、それに紐づく関数を一つ取り出して実行します。
16
+ そのイベント実行が終われば次のイベント発火条件を満たしたか否かを探しに行きます。
17
+
14
18
  > ```JavaScript
15
19
  > function main () {
16
20
  > request.get(options, function (error, response, body) {
@@ -24,14 +28,19 @@
24
28
 
25
29
  - main関数が実行される
26
30
  - request.getメソッドを実行
31
+ - request.getメソッド内、先方のWebサイトにHTTPのGETリクエストを発射(レスポンスを待たずに次へ)
27
32
  - request.getメソッドはイベントループ置き場に、「HTTPアクセスの結果が帰ってきたら」をトリガーに第二引数の関数を設定
33
+ - request.getメソッドはイベント登録が完了したので動作終了
28
34
  - main関数は正常終了、returnはないのでundefinedを返す
29
35
 
36
+ 大まかにはこういう挙動になっているはずです。
37
+
30
- ういう挙動になるで、絶対にundefinedが帰ります。
38
+ このままmain関数を実行すれば絶対にundefinedが帰ります。
39
+ イベントループ時に`return body`部分の関数を実行していますが、
31
- `return body`を内部に持っている関数はイベントループが実行していますが、イベントループ自体は引数を必要としていないので戻り値のbodyは残念ながら捨てられてしいます。
40
+ イベントループ自体は引数を必要としていないので戻り値のbodyはそのまま捨てられます。
41
+
32
42
  従って、質問文で`main() + sub()`とやると、`undefined-sub`になるのは正常な動作となります。
33
-
34
- HTTPアクセスの結果を待って`body`が欲しいのであれば、
43
+ もしHTTPアクセスの結果を待って`body`が欲しいのであれば、
35
44
  request.getの第二引数の関数内に全ての処理を格納する必要があります。
36
45
 
37
46
  ---

1

多少流れを修正

2018/11/16 10:16

投稿

miyabi-sun
miyabi-sun

スコア21465

answer CHANGED
@@ -28,15 +28,19 @@
28
28
  - main関数は正常終了、returnはないのでundefinedを返す
29
29
 
30
30
  こういう挙動になるので、絶対にundefinedが帰ります。
31
+ `return body`を内部に持っている関数はイベントループが実行していますが、イベントループ自体は引数を必要としていないので戻り値のbodyは残念ながら捨てられてしまいます。
31
- HTTPアクセスの結果を待つためにはrequest.getの第二引数の関数内全ての処理を格納す必要があります。
32
+ 従って質問文で`main() + sub()`とやると、`undefined-sub`のは正常な動作となります。
32
33
 
34
+ HTTPアクセスの結果を待って`body`が欲しいのであれば、
35
+ request.getの第二引数の関数内に全ての処理を格納する必要があります。
36
+
33
37
  ---
34
38
 
35
39
  以上、これがJSの非同期処理の流れです。
36
40
  まぁ、HTTPアクセスの結果を待ってから実行する第二引数の関数内で、
37
- 全てのやりたいことを記述しろって中々とち狂ったこと言ってますね。
41
+ 全てのやりたいことを記述しろですから、中々とち狂ったこと言ってますね。
38
42
 
39
43
  これがコールバック地獄の入り口になります。
40
44
 
41
- Node.jsはこのコールバック地獄とどう付き合うかでプログラミングテクニックを駆使る言語ですので、
45
+ Node.jsはこのコールバック地獄と付き合う為のテクニックが色々とありますので、
42
46
  色々と調べたりコードを書いてみてください。