📑
複数のデータ取得処理を高速にする
トップページなど情報量が多いページは、複数のfetch
処理ををする場合があります。どのように実装する事が適切か説明します。
1つずつデータを取得
fetchTopPageData
を内で、様々なデータを取得する為複数のfetch
を実行しています。1つずつデータを取得する直列タイプです。
今は2つのfetch
ですが、fetch
処理が増えると待ち時間が増えます。
type FetchResponse<T> = Promise<
| {
isSuccess: true;
data: T;
}
| {
isSuccess: false;
}
>;
type Fruit = {
name: string;
type: 'Apple' | 'Banana' | 'Peach';
};
const fetchFruits = (): FetchResponse<Fruit[]> => 'データ取得処理...';
type Food = {
name: string;
type: 'Meat' | 'Vegetable' | 'Dessert';
};
const fetchFoods = (): FetchResponse<Food[]> => 'データ取得処理...';
/**
* トップページで使用する様々なデータを取得する
*/
const fetchTopPageData = async () => {
const fruits = await fetchFruits();
if (!fruits.isSuccess) {
return 'fruits: 取得失敗';
}
const foods = await fetchFoods();
if (!foods.isSuccess) {
return 'foods: 取得失敗';
}
return {
fruits,
foods,
};
};
並列でデータを取得
Promise.all
を使用して並列でデータを取得します。fetchFruits
とfetchFoods
を並列で実行する為1つずつデータを取得するより早いです。実行結果は、Promise.all
に渡した順番で返却されます。以下の例では、fruits
, foods
です。
// 省略...
/**
* トップページで取得する様々なデータを取得する
*/
const fetchTopPageData = async () => {
const [fruits, foods] = await Promise.all([fetchFruits(), fetchFoods()]);
if (!fruits.isSuccess) {
return 'fruits: 取得失敗';
}
if (!foods.isSuccess) {
return 'foods: 取得失敗';
}
return {
fruits,
foods,
};
};
前提条件があるデータ取得処理
並列でデータを取得した方が速度的には早いですが、全ての状況で使える訳ではありません。前提条件があるような処理は、個別に取得した後Promise.all
で取得します。
例えば、Role
がAdmin
の場合にデータを取得する場合は、以下のように実装します。
-
fetchRole
のレスポンスがAdmin
である事を確認をする -
Admin
の場合でPromise.all
を使用して並列でデータ取得する
type FetchResponse<T> = Promise<
| {
isSuccess: true;
data: T;
}
| {
isSuccess: false;
}
>;
type Role = {
type: 'Admin' | 'Member';
};
type FetchRole = (p: { id: string }) => FetchResponse<Role>;
const fetchRole: FetchRole = () => 'データ取得処理...';
type Store = {
name: string;
address: string;
};
type FetchStores = () => FetchResponse<Store[]>;
const fetchStores: FetchStores = () => 'データ取得処理...';
type Employee = {
id: string;
name: string;
};
type FetchEmployees = () => FetchResponse<Employee[]>;
const fetchEmployees: FetchEmployees = () => 'データ取得処理...';
const fetchX = () => {};
const main = async () => {
const role = await fetchRole({ id: 'myId' });
if (!role.isSuccess) {
return '権限取得失敗';
}
if (role.data.type !== 'Admin') {
return '権限がありません。';
}
const [stores, employees] = await Promise.all([
fetchStores(),
fetchEmployees(),
]);
if (!stores.isSuccess) {
return '店舗一覧取得失敗しました。';
}
if (!employees.isSuccess) {
return '従業員一覧取得失敗しました。';
}
return {
stores,
employees,
};
};

ちょっと株式会社(chot-inc.com)のエンジニアブログです。 フロントエンドエンジニア募集中! カジュアル面接申し込みはこちらから chot-inc.com/recruit/iuj62owig
Discussion