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

回答編集履歴

2

ついき

2018/07/19 06:41

投稿

og24715
og24715

スコア832

answer CHANGED
@@ -1,3 +1,55 @@
1
+ ## 修正というか正しい非同期処理とその同期的処理
2
+
3
+ お二方から指摘がありますが、 pro() は呼び出した瞬間同期的に console.log(3) が実行されます。
4
+ というのも Promise を生成してますが引数に与えられたコールバック関数の中でいきなり `console.log(3)` としているからですね。
5
+ 例えば **3 秒待った後に 3 と出力** するような非同期関をコールバック関数として引数に与えるのならば以下のようになります。
6
+
7
+ ```
8
+ const output3 = () => new Promise(resolve => {
9
+ setTimeout(() => {
10
+ console.log('3');
11
+ resolve();
12
+ }, 3000)
13
+ });
14
+ ```
15
+
16
+ そして以下のコードを試してみてください。
17
+
18
+ ```
19
+ output3();
20
+ console.log(2);
21
+ console.log(1);
22
+ ```
23
+
24
+ `3 2 1` と出力されそうですが、実際は `2 1 3` となります。
25
+
26
+ というのも `output3` が Promise を返す非同期処理だからですね。
27
+ output3 の Promise の処理が完了していることを期待して、 次の console.log() を実行するには `await` キーワードを使用して、 Promise の完了を待つ必要があります。
28
+ しかし、 await キーワードは `async function` の中でしか使えないという制約があるので以下のようにします。
29
+ (トップレベル await が可能な仕組みが現在作られています。ちなみに GoogleChrome の デベロッパーコンソールもトップレベル await が可能)
30
+
31
+ ```
32
+ async function() {
33
+ await output3();
34
+ console.log(2);
35
+ console.log(1);
36
+ }
37
+ ```
38
+
39
+ 関数宣言しただけでは動かないので即時呼び出しする(即時関数)
40
+
41
+ ```
42
+ (async function() {
43
+ await output3();
44
+ console.log(2);
45
+ console.log(1);
46
+ })();
47
+ ```
48
+
49
+ これを実行すると、めでたく 3秒待って 3が出力され、続いて 2, 1 となります。????
50
+
51
+ ---
52
+
1
53
  > なぜ1 5と行かないでasync functionの中に入っていくのですか?(No.1/No.2)
2
54
 
3
55
  即時関数だから。さらに async function なので `2` の次に `5` が来るか、 `3` が来るかは保証できません。

1

修正

2018/07/19 06:41

投稿

og24715
og24715

スコア832

answer CHANGED
@@ -1,6 +1,6 @@
1
1
  > なぜ1 5と行かないでasync functionの中に入っていくのですか?(No.1/No.2)
2
2
 
3
- 即時関数だから。さらに async function なので `1` の次に `5` が来るか、 `2` が来るかは保証できません。
3
+ 即時関数だから。さらに async function なので `2` の次に `5` が来るか、 `3` が来るかは保証できません。
4
4
 
5
5
  > なぜawaitがあるとasync functionの外に行くのですか?(No.1)
6
6
 
@@ -8,7 +8,7 @@
8
8
 
9
9
  > なぜ2 4と行かないで2 3 4と表示されるのですか?(No.2)
10
10
 
11
- これは例が悪いですね。 pro() がもっと時間のかかる処理なら `1 2 4 5 3` となりそうですが、すぐ終わる処理なので順当に `1 2 3 4 5` となりました。これも async function なので `1` の後が `2` なのか `5` なのかは保証できません。
11
+ これは例が悪いですね。 pro() がもっと時間のかかる処理なら `1 2 4 5 3` となりそうですが、すぐ終わる処理なので順当に `1 2 3 4 5` となりました。これも async function なので `2` の後が `5` なのか `3` なのかは保証できません。
12
12
 
13
13
  ---
14
14