Async/await in TypeScript
This article explains async/await in TypeScript.
YouTube Video
Async/await in TypeScript
In TypeScript, async
is a keyword for concisely describing asynchronous operations and behaves similarly to JavaScript's async
/await
syntax. Async
functions are designed to make handling functions that return Promises more intuitive.
Basics of async
Functions
Functions declared with the async
keyword always return a Promise
. Here is a basic example:.
1async function fetchData(): Promise<string> {
2 return "Data received";
3}
4
5fetchData().then((data) => console.log(data)); // "Data received"
In this example, because the async
function always returns a Promise
, the returned value is automatically resolved using Promise.resolve
. In other words, "Data received"
becomes a Promise<string>
and is treated as an asynchronous operation.
The await
Keyword
The await
keyword can only be used inside an async
function. This provides the ability to pause and wait for the result of a Promise
before continuing with the function execution.
In the following example, asynchronous processing using fetch
is written with 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();
In this example, await
is used to wait for the completion of the Promise
returned by the fetch
function, and its result is assigned to the variable response
. Further, the result of response.json()
is also awaited.
Error Handling with async
/await
Errors that occur during asynchronous processing can be caught using the standard try...catch
syntax. If an error occurs at the await
part, that error is handled in the catch
block.
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();
In the above example, the result of the fetch
function is awaited using await
, and if an error occurs, it is handled with try...catch
.
Advantages of async
/await
-
Intuitive asynchronous processing: By using
async
/await
, the code flow is more intuitive than usingPromise
chains (then
orcatch
), allowing it to be written like synchronous processing. -
Easy error handling: Using
try...catch
simplifies error handling in asynchronous operations. You can write more readable code than by usingPromise
chains.
Return Values of async
Functions
An async
function always returns a Promise
. Therefore, even without explicitly returning a Promise
, asynchronous processing is possible by using the async
keyword.
1async function example() {
2 return 42;
3}
4
5example().then((result) => console.log(result)); // 42
In the code above, a synchronous value 42
is returned, but since it is inside an async
function, it is automatically converted to Promise.resolve(42)
.
Sequential Execution of Asynchronous Functions
When executing multiple asynchronous functions in succession, you can use await
to control their order.
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();
In this example, fetchData2
is executed after waiting for fetchData1
to complete. This is more readable compared to using a Promise
chain.
Parallel Execution
If you want to execute asynchronous operations in parallel, you can use Promise.all
to handle multiple Promises
simultaneously.
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();
In this case, fetchData1
and fetchData2
are executed at the same time, and the process proceeds after both are resolved. This allows for efficient handling of multiple asynchronous operations.
Summary
- An
async
function returns aPromise
, and by using theawait
keyword, you can wait for the result of an asynchronous operation. - By using
try...catch
, error handling in asynchronous operations becomes simpler. - By using
Promise.all
, it is possible to execute multiple asynchronous operations in parallel.
async
/await
is widely used in TypeScript and JavaScript because it allows for simpler description of asynchronous operations.
You can follow along with the above article using Visual Studio Code on our YouTube channel. Please also check out the YouTube channel.