非同期処理とは?
非同期処理とは、あるタスクを実行しつつ、他のタスクを並行して処理することです。
これにより、処理の待ち時間を最小限に抑え、効率的なプログラムを作成することができます。
コールバック関数
最も基本的な非同期処理の方法はコールバック関数を使用することです。
function fetchData(callback: (data: string) => void) {
setTimeout(() => {
callback("データ取得完了");
}, 1000);
}
fetchData((data) => {
console.log(data);
});
Promise
コールバック関数の欠点(コールバック地獄)を解消するために、Promiseが導入されました。Promiseは、非同期操作の完了や失敗を扱うオブジェクトです。
function fetchData(): Promise<string> {
return new Promise((resolve) => {
setTimeout(() => {
resolve("データ取得完了");
}, 1000);
});
}
fetchData().then((data) => {
console.log(data);
});
async/await
Promiseの構文をさらにシンプルにするために、async/awaitが登場しました。
これにより、非同期処理を同期処理のように書くことができます。
async function fetchData(): Promise<string> {
return new Promise((resolve) => {
setTimeout(() => {
resolve("データ取得完了");
}, 1000);
});
}
async function main() {
const data = await fetchData();
console.log(data);
}
main();
エラーハンドリング
Promiseでは.catchメソッドを使用し、async/awaitではtry...catchブロックを使用します。
function fetchData(): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("データ取得失敗"));
}, 1000);
});
}
fetchData().then((data) => {
console.log(data);
}).catch((error) => {
console.error(error);
});
async/awaitでのエラーハンドリング
async function fetchData(): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("データ取得失敗"));
}, 1000);
});
}
async function main() {
try {
const data = await fetchData();
console.log(data);
} catch (error) {
console.error(error);
}
}
main();
実践的な例
非同期処理の実践的な例として、APIからデータを取得するシナリオを考えます。
ここでは、Fetch APIを使用します。
async function fetchUserData(userId: number): Promise<any> {
const response = await fetch(`https://jsonplaceholder.typicode.com/users/${userId}`);
if (!response.ok) {
throw new Error('データ取得失敗');
}
return response.json();
}
async function main() {
try {
const userData = await fetchUserData(1);
console.log(userData);
} catch (error) {
console.error(error);
}
}
main();
まとめ
非同期処理は、基本的なコールバック関数から始まり、Promiseやasync/awaitを使用することで、より読みやすく、保守しやすいコードを書くことができます。