TypeScriptにおける非同期関数とPromiseの返却:サンプルコード
TypeScriptにおける非同期関数とPromiseの返却
非同期関数の定義
async
キーワードを用いて、非同期関数を定義します。この関数は、非同期処理を含む処理を実行します。
async function fetchData(url: string): Promise<string> {
// ... 非同期処理を含む処理
}
この例では、fetchData
という非同期関数を定義しています。この関数は、url
引数として渡されたURLからデータを取得する処理を実行します。
Promiseの返却
非同期処理の結果は、Promiseオブジェクトとして返却します。Promiseオブジェクトは、処理が完了したことを示すresolve
関数と、処理が失敗したことを示すreject
関数を持つオブジェクトです。
async function fetchData(url: string): Promise<string> {
const response = await fetch(url);
if (response.ok) {
const data = await response.text();
return data;
} else {
throw new Error('Failed to fetch data');
}
}
この例では、fetchData
関数がPromiseオブジェクトを返却しています。fetch
関数を使用してURLからデータを取得し、その結果に応じて、resolve
関数またはreject
関数を呼び出しています。
非同期関数の返却したPromiseオブジェクトは、then
メソッドとcatch
メソッドを用いて処理することができます。
fetchData('https://example.com')
.then(data => {
console.log(data);
})
.catch(error => {
console.error(error);
});
この例では、fetchData
関数を呼び出し、返却されたPromiseオブジェクトに対してthen
メソッドとcatch
メソッドをチェーンしています。then
メソッドは、Promiseが解決された場合に実行される処理を定義し、catch
メソッドは、Promiseが拒否された場合に実行される処理を定義します。
await
キーワードは、非同期処理が完了するまで待機します。Promise
オブジェクトは、非同期処理の結果を非同期的に処理する際に有用です。- TypeScriptでは、Promiseオブジェクトの型を指定することができます。
// データ型を定義
type UserData = {
name: string;
age: number;
};
// 非同期関数でAPIからユーザーデータを取得
async function getUserData(userId: number): Promise<UserData> {
const url = `https://api.example.com/users/${userId}`;
const response = await fetch(url);
if (response.ok) {
const data = await response.json();
return data;
} else {
throw new Error('Failed to fetch user data');
}
}
// 非同期関数を呼び出し、Promiseの処理
getUserData(123)
.then(userData => {
console.log(`User data: ${JSON.stringify(userData)}`);
})
.catch(error => {
console.error(`Error fetching user data: ${error.message}`);
});
解説
UserData
型を定義します。これは、APIから取得するユーザーデータの構造を表します。getUserData
という非同期関数を定義します。この関数は、userId
引数として渡されたユーザーIDに基づいて、APIからユーザーデータを取得します。fetch
関数を使用して、APIエンドポイントにリクエストを送信します。- レスポンスが正常 (
response.ok
) の場合、response.json()
を使用してJSONデータを解析し、UserData
型のオブジェクトとして返します。 - レスポンスが正常でない場合、
Error
オブジェクトをスローし、Promiseを拒否します。 getUserData
関数を呼び出し、返却されたPromiseに対してthen
メソッドとcatch
メソッドをチェーンします。then
メソッドは、Promiseが解決された場合 (つまり、ユーザーデータが正常に取得された場合) に実行される処理を定義します。
- 上記のコードは、あくまでも一例です。実際の開発では、エラー処理や型ガードなどをより詳細に行う必要があります。
Promise
コンストラクタを用いて、Promiseオブジェクトを直接生成することができます。
function fetchData(url: string): Promise<string> {
return new Promise((resolve, reject) => {
fetch(url)
.then(response => {
if (response.ok) {
response.text().then(data => resolve(data));
} else {
reject(new Error('Failed to fetch data'));
}
})
.catch(error => reject(error));
});
}
この例では、fetchData
関数はPromiseコンストラクタを用いてPromiseオブジェクトを生成しています。resolve
関数とreject
関数引数として、非同期処理の完了時と失敗時の処理をそれぞれ渡します。
Promiseライブラリの利用
TypeScriptには、Promise
オブジェクトに関する様々なユーティリティ関数を提供するPromiseライブラリが用意されています。このライブラリを用いることで、より複雑な非同期処理を効率的に処理することができます。
import { Promise as P } from 'ts-promise';
function fetchData(url: string): P<string> {
return new P((resolve, reject) => {
fetch(url)
.then(response => {
if (response.ok) {
response.text().then(data => resolve(data));
} else {
reject(new Error('Failed to fetch data'));
}
})
.catch(error => reject(error));
});
}
この例では、ts-promise
ライブラリからPromise
クラスをインポートしています。Promiseライブラリを用いることで、then
メソッドやcatch
メソッドなどの操作がより簡潔になります。
非同期ジェネレータ関数
TypeScript 3.8以降では、非同期ジェネレータ関数を利用することができます。非同期ジェネレータ関数は、yield
キーワードを用いて非同期処理をイテレータとして処理することができます。
async function* fetchData(url: string): AsyncIterableIterator<string> {
const response = await fetch(url);
if (response.ok) {
for (const chunk of response.body.getReader()) {
const text = await chunk.text();
yield text;
}
} else {
throw new Error('Failed to fetch data');
}
}
(async () => {
for await (const data of fetchData('https://example.com')) {
console.log(data);
}
})();
この例では、fetchData
関数を非同期ジェネレータ関数として定義しています。yield
キーワードを用いて、非同期処理をイテレータとして処理し、取得したデータを逐次的に返却します。
- 上記の方法は、あくまでも一例です。それぞれの方法には利点と欠点があります。
- 状況に応じて適切な方法を選択することが重要です。
typescript