APIリクエストとか非同期処理をfor
文で何度か繰り返したい時に。
例えば、こんなfor
文を書いた時に、
var sum = 0
for (let i = 0; i <= 10; i++) {
exampleFunc(i).then(res => sum += res)
}
console.log(sum)
function exampleFunc(index) {
return new Promise((resolve, reject) => {
// 何か重い処理して、resultを返す
resolve(result)
)
}
このまま動かすと、for
文は「i=1
の時、exampleFunc
実行→レスポンス待たずに次へ→i=2
の時、exampleFunc
実行→…」という動作をする為、
console.log(sum)
で表示される値が不安(apiのレスポンスの速度によって変わってしまう)
正常な動作として、「i=1
の時、exampleFunc
実行→レスポンスを受け取る→i=2
の時、exampleFunc
実行→レスポンスを受け取る→…」となってほしい。
ということで、実現するためのコード
var tasks = []
var sum = 0
for (let i = 0; i <= 10; i++) {
tasks.push(exampleFunc(i).then(res => sum += res))
}
Promise.all(tasks).then(result => {
// resultは上記apiのレスポンスの配列
// 上記の場合は、レスポンスがない為、undefinedが詰まった配列になる
console.log(sum)
}
function exampleFunc(index) {
return new Promise((resolve, reject) => {
// 何か重い処理して、resultを返す
resolve(result)
)
}
Promise.all
にPromise
を返すfunction
の配列ぶち込むと、配列内の全てがresolve
を返し次第、then
内が実行される
(おそらく、内部のfunction
は、for
文の内部で配列にpush
される時点から開始される)
まとめ
setTimeout
で時間差で実行させる方法もあるが、こっちの方が確実に「終了次第、実行」を実現できる。