TypeScriptにおけるasync/await
この記事ではTypeScriptにおけるasync/awaitについて説明します。
YouTube Video
TypeScriptにおけるasync/await
TypeScriptにおけるasyncは、非同期処理を簡潔に記述するためのキーワードで、JavaScriptのasync/await構文と同様の動作をします。async関数は、Promiseを返す関数をより直感的に扱えるように設計されています。
async 関数の基本
asyncキーワードを使って宣言された関数は、常にPromiseを返します。以下はその基本的な例です。
1async function fetchData(): Promise<string> {
2 return "Data received";
3}
4
5fetchData().then((data) => console.log(data)); // "Data received"
この例では、async関数は常にPromiseを返すため、returnされた値は自動的にPromise.resolveされます。つまり、"Data received"はPromise<string>となり、非同期処理として扱われます。
await キーワード
awaitキーワードは、async関数内でしか使えません。これは、Promiseの結果が返ってくるまで関数の実行を一時停止し、待機する機能を提供します。
次の例では、fetchを使った非同期処理をasync/awaitで記述しています。
1async function getUserData() {
2 try {
3 const response = await fetch("https://codesparklab.com/json/example.json");
4 const data = await response.json();
5 console.log(data);
6 } catch (error) {
7 console.error("Error fetching user data:", error);
8 }
9}
10
11getUserData();この例では、awaitを使ってfetch関数が返すPromiseの完了を待ち、その結果を変数responseに代入します。さらに、response.json()の結果もawaitで待機します。
async/awaitのエラーハンドリング
非同期処理中に発生するエラーは、通常のtry...catch構文を使ってキャッチできます。awaitの部分でエラーが発生した場合、catchブロックでそのエラーを処理します。
1async function fetchDataWithErrorHandling() {
2 try {
3 const response = await fetch('https://invalid.codesparklab.com/');
4 if (!response.ok) {
5 throw new Error(`HTTP error! status: ${response.status}`);
6 }
7 const data = await response.json();
8 console.log(data);
9 } catch (error) {
10 console.error("Fetch error:", error);
11 }
12}
13
14fetchDataWithErrorHandling();上記の例では、awaitによってfetch関数の結果を待機しつつ、エラーが発生した場合にtry...catchでエラーを処理しています。
async/awaitの利点
-
直感的な非同期処理:
async/awaitを使うことで、Promiseチェーン(thenやcatch)を使った場合よりもコードの流れが直感的で、同期処理のように記述できる。 -
エラーハンドリングが簡単:
try...catchを使うことで、非同期処理におけるエラーハンドリングがシンプルになります。Promiseチェーンを使うよりも読みやすいコードが書けます。
async 関数の戻り値
async関数は常にPromiseを返します。そのため、明示的にPromiseを返さなくても、asyncキーワードを使えば非同期処理が可能です。
1async function example() {
2 return 42;
3}
4
5example().then((result) => console.log(result)); // 42
上記のコードでは、42という同期的な値が返されていますが、async関数内であるため、自動的にPromise.resolve(42)に変換されます。
非同期関数の連続実行
複数の非同期関数を連続して実行する場合は、awaitを使ってその順序を制御できます。
1async function fetchData(url: string): Promise<any> {
2 try {
3 const response = await fetch(url);
4 return await response.json();
5 } catch (error) {
6 console.error("Error fetching user data:", error);
7 }
8}
9
10async function fetchData1(): Promise<any> {
11 return await fetchData("https://codesparklab.com/json/example.json");
12}
13
14async function fetchData2(): Promise<any> {
15 return await fetchData("https://codesparklab.com/json/example2.json");
16}
17
18async function processData() {
19 const data1 = await fetchData1();
20 console.log(data1);
21
22 const data2 = await fetchData2();
23 console.log(data2);
24}
25
26processData();この例では、fetchData1の完了を待ってからfetchData2を実行しています。これはPromiseチェーンを使った方法に比べてコードの可読性が高いです。
並列実行
非同期処理を並列で実行したい場合、Promise.allを使って同時に複数のPromiseを処理できます。
1async function fetchData(url: string): Promise<any> {
2 try {
3 const response = await fetch(url);
4 return await response.json();
5 } catch (error) {
6 console.error("Error fetching user data:", error);
7 }
8}
9
10async function fetchData1(): Promise<any> {
11 return await fetchData("https://codesparklab.com/json/example.json");
12}
13
14async function fetchData2(): Promise<any> {
15 return await fetchData("https://codesparklab.com/json/example2.json");
16}
17
18async function fetchMultipleData() {
19 const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);
20 console.log(data1);
21 console.log(data2);
22}
23
24fetchMultipleData();この場合、fetchData1とfetchData2が同時に実行され、両方が解決されるのを待ってから処理を進めます。これにより、効率的に複数の非同期処理を行うことができます。
まとめ
async関数はPromiseを返し、awaitキーワードを使うことで非同期処理の結果を待機します。try...catchを使うことで、非同期処理におけるエラーハンドリングが簡単になります。Promise.allを使うことで、複数の非同期処理を並列に実行することが可能です。
async/awaitは非同期処理をよりシンプルに記述できるため、TypeScriptやJavaScriptで広く使用されています。
YouTubeチャンネルでは、Visual Studio Codeを用いて上記の記事を見ながら確認できます。 ぜひYouTubeチャンネルもご覧ください。