回答編集履歴
3
リファクタリング
answer
CHANGED
|
@@ -37,16 +37,19 @@
|
|
|
37
37
|
setTimeout(() => resolve(num), 500)
|
|
38
38
|
);
|
|
39
39
|
|
|
40
|
-
const call = num =>
|
|
40
|
+
const call = num => {
|
|
41
|
+
// とりま空のPromiseを宣言
|
|
41
42
|
let promise = Promise.resolve(null);
|
|
42
43
|
const results = [];
|
|
43
44
|
for (let i = 0; i < 5; i++) {
|
|
44
45
|
// このように代入していかないと直列繋ぎで実行してくれない
|
|
45
46
|
promise = promise.then(() =>
|
|
46
|
-
fn1(num + i).then(
|
|
47
|
+
fn1(num + i).then(it => results.push(it))
|
|
47
48
|
)
|
|
48
49
|
}
|
|
50
|
+
// やる事が全部終わったら結果をresultsにすげ替える
|
|
49
|
-
return promise.then(() => results)
|
|
51
|
+
return promise.then(() => results);
|
|
52
|
+
}
|
|
50
53
|
|
|
51
54
|
call(0).then(console.log);
|
|
52
55
|
// Promise {<pending>}
|
2
async/awaitを意訳したらfor文でつなげるコードより格段に良くなったので差し替え
answer
CHANGED
|
@@ -37,56 +37,23 @@
|
|
|
37
37
|
setTimeout(() => resolve(num), 500)
|
|
38
38
|
);
|
|
39
39
|
|
|
40
|
-
const call = num => {
|
|
40
|
+
const call = num => new Promise(resolve => {
|
|
41
|
-
let promise = Promise.resolve(
|
|
41
|
+
let promise = Promise.resolve(null);
|
|
42
|
+
const results = [];
|
|
42
43
|
for (let i = 0; i < 5; i++) {
|
|
43
|
-
// 代入していかないと直列繋ぎ
|
|
44
|
+
// このように代入していかないと直列繋ぎで実行してくれない
|
|
44
|
-
promise = promise.then(
|
|
45
|
+
promise = promise.then(() =>
|
|
45
|
-
new Promise(resolve =>
|
|
46
|
-
|
|
46
|
+
fn1(num + i).then(result => results.push(result))
|
|
47
|
-
results.push(it);
|
|
48
|
-
resolve(results);
|
|
49
|
-
})
|
|
50
|
-
)
|
|
51
47
|
)
|
|
52
48
|
}
|
|
53
|
-
return promise;
|
|
49
|
+
return promise.then(() => results).then(resolve);
|
|
54
|
-
};
|
|
55
50
|
|
|
56
51
|
call(0).then(console.log);
|
|
57
52
|
// Promise {<pending>}
|
|
58
53
|
// 500ms*5の約2.5秒ほど待ってから: [0, 1, 2, 3, 4]
|
|
59
54
|
```
|
|
60
55
|
|
|
61
|
-
しかし、結果が入った配列をバケツリレーにしているのでこれだと歪になっちゃう
|
|
62
|
-
`fn1`を数値と配列受け取るように改造した方がいいかな?
|
|
63
|
-
|
|
64
|
-
```JavaScript
|
|
65
|
-
// こっちはちょっと複雑になったけど
|
|
66
|
-
const fn2 = (num, results) => new Promise(resolve =>
|
|
67
|
-
setTimeout(() => {
|
|
68
|
-
results.push(num);
|
|
69
|
-
resolve(results);
|
|
70
|
-
}, 500)
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
const call = num => {
|
|
74
|
-
let promise = Promise.resolve([]);
|
|
75
|
-
for (let i = 0; i < 5; i++) {
|
|
76
|
-
promise = promise.then(results =>
|
|
77
|
-
// こっちはスッキリ書けた
|
|
78
|
-
fn2(num + i, results)
|
|
79
|
-
)
|
|
80
|
-
}
|
|
81
|
-
return promise;
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
call(0).then(console.log);
|
|
85
|
-
// Promise {<pending>}
|
|
86
|
-
// 500ms*5の約2.5秒ほど待ってから: [0, 1, 2, 3, 4]
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
|
|
56
|
+
実はES2017で追加された[async/await](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function)という糖衣構文でPromiseを同期処理っぽく書く事が出来る。
|
|
90
57
|
Lhankor_Mhyさんの回答はその書き方であり、普通にfor文で処理出来るようになる。
|
|
91
58
|
|
|
92
59
|
```JavaScript
|
|
@@ -95,6 +62,7 @@
|
|
|
95
62
|
setTimeout(() => resolve(num), 500)
|
|
96
63
|
);
|
|
97
64
|
|
|
65
|
+
// なんだこの平易なコードは!?
|
|
98
66
|
const call = async num => {
|
|
99
67
|
const results = [];
|
|
100
68
|
for (let i = 0; i < 5; i++) {
|
|
@@ -106,4 +74,6 @@
|
|
|
106
74
|
call(0).then(console.log);
|
|
107
75
|
// Promise {<pending>}
|
|
108
76
|
// 500ms*5の約2.5秒ほど待ってから: [0, 1, 2, 3, 4]
|
|
109
|
-
```
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
このasync版の`call`関数は上記のコードとほぼ同様の動きをしてくれる。
|
1
async/awaitを追加
answer
CHANGED
|
@@ -84,4 +84,26 @@
|
|
|
84
84
|
call(0).then(console.log);
|
|
85
85
|
// Promise {<pending>}
|
|
86
86
|
// 500ms*5の約2.5秒ほど待ってから: [0, 1, 2, 3, 4]
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
更にそこからES2017で追加された[async/await](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Statements/async_function)という糖衣構文でPromiseを同期処理っぽく書く事が出来る。
|
|
90
|
+
Lhankor_Mhyさんの回答はその書き方であり、普通にfor文で処理出来るようになる。
|
|
91
|
+
|
|
92
|
+
```JavaScript
|
|
93
|
+
// やはり長いので500msに
|
|
94
|
+
const fn1 = num => new Promise(resolve =>
|
|
95
|
+
setTimeout(() => resolve(num), 500)
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
const call = async num => {
|
|
99
|
+
const results = [];
|
|
100
|
+
for (let i = 0; i < 5; i++) {
|
|
101
|
+
results.push(await fn1(num + i));
|
|
102
|
+
}
|
|
103
|
+
return results;
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
call(0).then(console.log);
|
|
107
|
+
// Promise {<pending>}
|
|
108
|
+
// 500ms*5の約2.5秒ほど待ってから: [0, 1, 2, 3, 4]
|
|
87
109
|
```
|