2022.12.26
array.map()内で実行する非同期関数をasync/awaitで同期的に処理する方法
概要
今回は連続して実行したい非同期処理のサンプルとして 郵便番号から住所を取得するAPI を利用します。
このAPIにリクエストしたい郵便番号を配列で保持していて、その配列内の各要素を使って順番にリクエストし、すべてのレスポンスが返ってきてからコンソールに結果を表示します。
array.map()内の関数でasync/awaitするだけでは期待通りにならない
当然といえば当然なのですが、以下のように書くと期待通りになりません。
TypeScript_____NG_____const postalCodes = ['7830060', '1030004'];
const addresses = postalCodes.map(async (postalCode) => {
const response = await fetch(`https://zipcloud.ibsnet.co.jp/api/search?zipcode=${postalCode}`);
const { results } = await response.json();
return results[0].address1 + results[0].address2 + results[0].address3;
})
console.log(addresses);
// 結果(Promiseが解決できていない)
// [[object Promise] { ... }, [object Promise] { ... }]
非同期処理の配列をPromise.all()に渡しPromise.all()をawaitする
続いて、期待通りになるサンプルです。
TypeScript_____OK_____const getAddresses = async (postalCodes: string[]) => await Promise.all(postalCodes.map(async (postalCode): Promise<string> => {
const response = await fetch(`https://zipcloud.ibsnet.co.jp/api/search?zipcode=${postalCode}`);
const { results } = await response.json();
return results[0].address1 + results[0].address2 + results[0].address3;
}));
(async () => {
console.log(await getAddresses(['7830060', '1030004']));
})();
// 結果
// ["高知県南国市蛍が丘", "東京都中央区東日本橋"]
こうすることで、mapからのPromiseオブジェクトの配列ひとつひとつをawaitして処理を進められます。
Nuxtのサイトマップ生成などでいい感じに利用できます。