やりたいこと
配列 'Array'の要素の数だけ、API 'featchData'と通信を行い、その処理が全て終わり次第、後続の処理を行いたい
実装サンプル
let Array = [{name: 'Tanaka'},{name: 'Suzuki'}]
const startFunction = async () => {
for (let item of Array) {
// featchDataをawaitableにするため、新しいPromiseを作成します
await new Promise((resolve) => {
featchData(
{
query: item.name,
},
(res) => {
console.log('res =====', res)
resolve() // 処理が完了したらPromiseをresolveします
},
(err) => {
console.log('err', err)
resolve() // エラーでもPromiseをresolveしてループを続行します
}
)
})
}
// 以下は、上記のループが完全に終了した後に実行されます
console.log('ループ終了!')
}
解説
async/awaitを使用してループ処理が終わるのを待つことができます。
ただし、forEachだとasync/awaitが期待通りに動作しないため、代わりにfor...ofループを使用しています。
このコードでは、await new Promiseの部分でfeatchDataの処理が完了するのを待つようにしており、こ
れにより、各要素での処理が完全に終了した後に次の要素へ移動、全ての要素の処理が終わった後にconsole.log('ループ終了!')を行っています。
エラーが発生したときにループを終了したいパターン
上記の場合においては、非同期処理がエラーで終了した場合でもループは続行します。エラーが発生しても特定の処理を停止したくない場合に便利です。
もしエラーが発生したらループを終了(または例外をスロー)したい場合は、rejectとtry/catchを使用して以下のように実装できます。
実装サンプル
const startFunction = async () => {
for (let item of Array) {
try {
await new Promise((resolve, reject) => {
featchData(
{
query: item.name,
},
(res) => {
console.log('res =====', res)
resolve() // 処理が完了したらPromiseをresolveします
},
(err) => {
console.log('err', err)
reject(err) // エラーが発生したらPromiseをrejectします
}
)
})
} catch (err) {
// エラーハンドリングをここで行うことができます
// または、エラーを外部に伝播させるために再度throwすることもできます
throw err
}
}
// ループが完全に終了した後に実行されます
console.log('ループ終了!')
}
上記では、エラーが発生した場合、そのエラーがcatchされ、処理を停止します。その後、エラーをハンドリングするためのコードを実行できます。
以上です。ぜひ参考にしていただければ幸いです。