回答編集履歴
9
テキスト修正
answer
CHANGED
@@ -79,7 +79,7 @@
|
|
79
79
|
### 3. 最後の文字まで表示するのを一つのPromiseにする。
|
80
80
|
|
81
81
|
|
82
|
-
上記の 1. と 2. とは異なり、「200ミリ秒間隔でひと文字ずつ、最後の文字まで表示する」という処理をひとつの Promise にすることもできます。
|
82
|
+
上記の 1. と 2. とは異なり、「200ミリ秒間隔でひと文字ずつ、最後の文字まで表示する」という処理をひとつの Promise にすることもできます。以下のそのコード例です。
|
83
83
|
```javascript
|
84
84
|
const addTypingMovement = (word, target) => new Promise(
|
85
85
|
resolve => {
|
@@ -106,9 +106,12 @@
|
|
106
106
|
finishTitleCall(message);
|
107
107
|
})();
|
108
108
|
```
|
109
|
-
|
109
|
+
|
110
|
-
|
111
110
|
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/bcm7jgzw/14/](https://jsfiddle.net/jun68ykt/bcm7jgzw/14/)
|
112
111
|
|
112
|
+
上記では、
|
113
|
+
- `setTimeout`の替わりに`setInterval`を使っています。
|
114
|
+
- 文字列全体が表示されるまでをひとつの Promise にするので、 `Promise.all` は使わなくなっています。
|
115
|
+
- `Done.`という文字列を `resolve`の引数で返させるようにしました。
|
113
116
|
|
114
117
|
以上、参考になれば幸いです。
|
8
テキスト修正
answer
CHANGED
@@ -79,24 +79,23 @@
|
|
79
79
|
### 3. 最後の文字まで表示するのを一つのPromiseにする。
|
80
80
|
|
81
81
|
|
82
|
-
上記の 1. と 2. とは異なり、「200ミリ秒間隔で
|
82
|
+
上記の 1. と 2. とは異なり、「200ミリ秒間隔でひと文字ずつ、最後の文字まで表示する」という処理をひとつの Promise にすることもできます。この場合は Promise.all は使わず、以下のようになります。
|
83
83
|
```javascript
|
84
|
-
const addTypingMovement = (word, target) =>
|
84
|
+
const addTypingMovement = (word, target) => new Promise(
|
85
|
-
|
85
|
+
resolve => {
|
86
|
-
|
86
|
+
const printTarget = document.querySelector(target);
|
87
|
-
|
88
|
-
|
87
|
+
let i = 0;
|
89
88
|
const intervalId = setInterval(
|
90
89
|
() => {
|
91
|
-
if (
|
90
|
+
if (i < word.length) {
|
92
|
-
printTarget.textContent
|
91
|
+
printTarget.textContent = word.substring(0, ++ i);
|
93
92
|
} else {
|
94
93
|
clearInterval(intervalId);
|
95
94
|
resolve('Done.');
|
96
95
|
}
|
97
96
|
}, 200);
|
98
|
-
});
|
99
|
-
}
|
97
|
+
}
|
98
|
+
);
|
100
99
|
|
101
100
|
const finishTitleCall = (message) => {
|
102
101
|
document.querySelector('#result').textContent = message;
|
@@ -109,7 +108,7 @@
|
|
109
108
|
```
|
110
109
|
また上記では `Done.`という文字列を `resolve`の引数で返させました。
|
111
110
|
|
112
|
-
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/bcm7jgzw/
|
111
|
+
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/bcm7jgzw/14/](https://jsfiddle.net/jun68ykt/bcm7jgzw/14/)
|
113
112
|
|
114
113
|
|
115
114
|
以上、参考になれば幸いです。
|
7
テキスト修正
answer
CHANGED
@@ -86,7 +86,6 @@
|
|
86
86
|
const printTarget = document.querySelector(target);
|
87
87
|
|
88
88
|
return new Promise(resolve => {
|
89
|
-
let i = 0;
|
90
89
|
const intervalId = setInterval(
|
91
90
|
() => {
|
92
91
|
if (wordArray.length > 0) {
|
@@ -110,7 +109,7 @@
|
|
110
109
|
```
|
111
110
|
また上記では `Done.`という文字列を `resolve`の引数で返させました。
|
112
111
|
|
113
|
-
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/bcm7jgzw/
|
112
|
+
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/bcm7jgzw/5/](https://jsfiddle.net/jun68ykt/bcm7jgzw/5/)
|
114
113
|
|
115
114
|
|
116
115
|
以上、参考になれば幸いです。
|
6
テキスト修正
answer
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
こんにちは
|
2
2
|
|
3
|
+
この回答では3つのコードを挙げます。ご質問のタイトルに、
|
4
|
+
|
5
|
+
> for文内にsetTimeoutがある関数に対して、・・・
|
6
|
+
|
7
|
+
|
8
|
+
とあったので、 まずご質問のコードにある forループを生かしたコードを回答します。その後、for文を使わないコードを2つ挙げます。
|
9
|
+
|
10
|
+
### 1. forループで、各文字を追加するPromiseの配列を作る。
|
11
|
+
|
3
12
|
各文字を追加していく処理をひとつのPromiseにして、それらがすべてresolve されたら、Doneを表示するという前後関係を担保するために、 [Promise.all](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise/all) を使えばよいかと思います。
|
4
13
|
|
5
14
|
以下、ご質問に挙げられているコードに、上記の趣旨の追加をしたものです。
|
@@ -34,8 +43,11 @@
|
|
34
43
|
|
35
44
|
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/6wsp3onu/6/](https://jsfiddle.net/jun68ykt/6wsp3onu/6/)
|
36
45
|
|
37
|
-
上記のコードで、Promiseの配列を作るところの for文を [map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map) を使って書き換え、 すべての文字が `target` に追加されたら、Done を表示するために `async`, `await` を使った例が以下です。
|
38
46
|
|
47
|
+
### 2. forの替わりにmapを、前後関係の制御にasync/awaitを使用
|
48
|
+
|
49
|
+
上記 1. のコードで、Promiseの配列を作るところの for文を [map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map) を使って書き換え、 すべての文字が `target` に追加されたら、Done を表示するために `async`, `await` を使った例が以下です。
|
50
|
+
|
39
51
|
```javascript
|
40
52
|
const addTypingMovement = (word, target) => {
|
41
53
|
|
@@ -64,11 +76,10 @@
|
|
64
76
|
```
|
65
77
|
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/6wsp3onu/25/](https://jsfiddle.net/jun68ykt/6wsp3onu/25/)
|
66
78
|
|
67
|
-
|
79
|
+
### 3. 最後の文字まで表示するのを一つのPromiseにする。
|
68
80
|
|
69
|
-
### 追記
|
70
81
|
|
71
|
-
|
82
|
+
上記の 1. と 2. とは異なり、「200ミリ秒間隔で各文字を追加するのを、最後の文字まで行う」という処理をひとつの Promise にすることもできます。この場合は Promise.all は使わず、以下のようになります。
|
72
83
|
```javascript
|
73
84
|
const addTypingMovement = (word, target) => {
|
74
85
|
const wordArray = [...word];
|
@@ -99,4 +110,7 @@
|
|
99
110
|
```
|
100
111
|
また上記では `Done.`という文字列を `resolve`の引数で返させました。
|
101
112
|
|
102
|
-
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/bcm7jgzw/4/](https://jsfiddle.net/jun68ykt/bcm7jgzw/4/)
|
113
|
+
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/bcm7jgzw/4/](https://jsfiddle.net/jun68ykt/bcm7jgzw/4/)
|
114
|
+
|
115
|
+
|
116
|
+
以上、参考になれば幸いです。
|
5
テキスト修正
answer
CHANGED
@@ -78,11 +78,12 @@
|
|
78
78
|
let i = 0;
|
79
79
|
const intervalId = setInterval(
|
80
80
|
() => {
|
81
|
+
if (wordArray.length > 0) {
|
81
|
-
|
82
|
+
printTarget.textContent += wordArray.shift();
|
82
|
-
|
83
|
+
} else {
|
83
84
|
clearInterval(intervalId);
|
84
|
-
resolve('Done.');
|
85
|
+
resolve('Done.');
|
85
|
-
}
|
86
|
+
}
|
86
87
|
}, 200);
|
87
88
|
});
|
88
89
|
}
|
@@ -96,6 +97,6 @@
|
|
96
97
|
finishTitleCall(message);
|
97
98
|
})();
|
98
99
|
```
|
99
|
-
上記では `Done.`という文字列を `resolve`の引数で返させました。
|
100
|
+
また上記では `Done.`という文字列を `resolve`の引数で返させました。
|
100
101
|
|
101
|
-
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/
|
102
|
+
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/bcm7jgzw/4/](https://jsfiddle.net/jun68ykt/bcm7jgzw/4/)
|
4
テキスト修正
answer
CHANGED
@@ -96,6 +96,6 @@
|
|
96
96
|
finishTitleCall(message);
|
97
97
|
})();
|
98
98
|
```
|
99
|
-
上記では `Done.`という文字列を `
|
99
|
+
上記では `Done.`という文字列を `resolve`の引数で返させました。
|
100
100
|
|
101
101
|
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/08axgkho/16/](https://jsfiddle.net/jun68ykt/08axgkho/16/)
|
3
テキスト修正
answer
CHANGED
@@ -64,4 +64,38 @@
|
|
64
64
|
```
|
65
65
|
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/6wsp3onu/25/](https://jsfiddle.net/jun68ykt/6wsp3onu/25/)
|
66
66
|
|
67
|
-
以上、参考になれば幸いです。
|
67
|
+
以上、参考になれば幸いです。
|
68
|
+
|
69
|
+
### 追記
|
70
|
+
|
71
|
+
別のやり方として、「200ミリ秒間隔で各文字を追加するのを、最後の文字まで行う」という処理をひとつの Promise にする方法もあります。この場合は Promise.all は使わず、以下のようになります。
|
72
|
+
```javascript
|
73
|
+
const addTypingMovement = (word, target) => {
|
74
|
+
const wordArray = [...word];
|
75
|
+
const printTarget = document.querySelector(target);
|
76
|
+
|
77
|
+
return new Promise(resolve => {
|
78
|
+
let i = 0;
|
79
|
+
const intervalId = setInterval(
|
80
|
+
() => {
|
81
|
+
printTarget.textContent += wordArray[i ++];
|
82
|
+
if (i === wordArray.length) {
|
83
|
+
clearInterval(intervalId);
|
84
|
+
resolve('Done.');
|
85
|
+
}
|
86
|
+
}, 200);
|
87
|
+
});
|
88
|
+
}
|
89
|
+
|
90
|
+
const finishTitleCall = (message) => {
|
91
|
+
document.querySelector('#result').textContent = message;
|
92
|
+
}
|
93
|
+
|
94
|
+
(async () => {
|
95
|
+
const message = await addTypingMovement('Hello World.', '#typing');
|
96
|
+
finishTitleCall(message);
|
97
|
+
})();
|
98
|
+
```
|
99
|
+
上記では `Done.`という文字列を `resole`の引数で返させました。
|
100
|
+
|
101
|
+
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/08axgkho/16/](https://jsfiddle.net/jun68ykt/08axgkho/16/)
|
2
テキスト修正
answer
CHANGED
@@ -62,6 +62,6 @@
|
|
62
62
|
})();
|
63
63
|
|
64
64
|
```
|
65
|
-
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/6wsp3onu/
|
65
|
+
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/6wsp3onu/25/](https://jsfiddle.net/jun68ykt/6wsp3onu/25/)
|
66
66
|
|
67
67
|
以上、参考になれば幸いです。
|
1
テキスト修正
answer
CHANGED
@@ -32,4 +32,36 @@
|
|
32
32
|
|
33
33
|
以下は、ご質問に挙げられている jsFiddle をFork して、上記の修正版にしたものです。
|
34
34
|
|
35
|
-
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/6wsp3onu/6/](https://jsfiddle.net/jun68ykt/6wsp3onu/6/)
|
35
|
+
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/6wsp3onu/6/](https://jsfiddle.net/jun68ykt/6wsp3onu/6/)
|
36
|
+
|
37
|
+
上記のコードで、Promiseの配列を作るところの for文を [map](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Array/map) を使って書き換え、 すべての文字が `target` に追加されたら、Done を表示するために `async`, `await` を使った例が以下です。
|
38
|
+
|
39
|
+
```javascript
|
40
|
+
const addTypingMovement = (word, target) => {
|
41
|
+
|
42
|
+
const printTarget = document.querySelector(target);
|
43
|
+
|
44
|
+
return [...word].map((char, i) => new Promise(
|
45
|
+
resolve => {
|
46
|
+
setTimeout(() => {
|
47
|
+
printTarget.textContent += char;
|
48
|
+
resolve();
|
49
|
+
}, i * 200);
|
50
|
+
})
|
51
|
+
);
|
52
|
+
|
53
|
+
}
|
54
|
+
|
55
|
+
const finishTitleCall = () => {
|
56
|
+
document.querySelector('#result').textContent = 'Done.';
|
57
|
+
}
|
58
|
+
|
59
|
+
(async () => {
|
60
|
+
await Promise.all(addTypingMovement('Hello World.', '#typing'));
|
61
|
+
finishTitleCall();
|
62
|
+
})();
|
63
|
+
|
64
|
+
```
|
65
|
+
- **動作確認用 jsFiddle:** [https://jsfiddle.net/jun68ykt/6wsp3onu/24/](https://jsfiddle.net/jun68ykt/6wsp3onu/24/)
|
66
|
+
|
67
|
+
以上、参考になれば幸いです。
|