Async/await trong JavaScript
Trong bài viết này, chúng tôi sẽ giải thích về async/await trong JavaScript.
YouTube Video
Async/await trong JavaScript
async (và await) trong JavaScript là các tính năng được thiết kế để giúp việc viết các hoạt động bất đồng bộ trở nên trực quan và dễ đọc hơn. Bằng cách sử dụng điều này, bạn có thể giảm độ phức tạp của các hàm gọi lại (callback) truyền thống và chuỗi Promise, và viết mã bất đồng bộ theo cách giống như mã đồng bộ.
Hàm async
async được sử dụng để định nghĩa một hàm là hàm bất đồng bộ. Một hàm async luôn trả về một Promise. Trong một hàm được đánh dấu bằng async, bạn có thể sử dụng await để đợi kết quả của một Promise được trả về.
Cú pháp cơ bản của một hàm async
1async function myAsyncFunction() {
2 // Write asynchronous processing here
3 return 'Result'; // Return a Promise
4}Trong trường hợp này, gọi myAsyncFunction() sẽ tự động trả về một đối tượng Promise. Khi Promise được giải quyết, kết quả của nó trở thành giá trị được trả về bởi return.
Ví dụ: Hàm async cơ bản
1async function greet() {
2 return 'Hello, World!';
3}
4
5greet().then((message) => {
6 console.log(message); // Displays "Hello, World!"
7});await
await được sử dụng để đợi một Promise được giải quyết. Bằng cách sử dụng await, bạn có thể tạm dừng việc thực thi cho đến khi Promise được giải quyết và nhận kết quả của Promise. await chỉ có thể được sử dụng bên trong một hàm async.
Ví dụ: Cách sử dụng await
1async function fetchData() {
2 // Wait for the result of the Promise
3 const data = await fetch('https://codesparklab.com/json/example.json');
4 // Wait for the asynchronous operation to complete
5 const jsonData = await data.json();
6 // Retrieve and display the data
7 console.log(jsonData);
8}
9
10fetchData();Trong ví dụ trên, nó chờ Promise được trả về bởi hàm fetch bằng await, và sau đó thực hiện các hoạt động bất đồng bộ khác bằng cách sử dụng kết quả.
Xử lý lỗi với async/await
Nếu một lỗi xảy ra bên trong hàm async, lỗi đó sẽ được coi như là một reject của Promise. Bạn có thể sử dụng câu lệnh try...catch để thực hiện xử lý lỗi.
Ví dụ: Xử lý lỗi
1async function fetchData() {
2 try {
3 // Invalid URL
4 const data = await fetch('https://invalid.codesparklab.com/');
5 const jsonData = await data.json();
6 console.log(jsonData);
7 } catch (error) {
8 // Catch the error
9 console.error('Failed to fetch data:', error);
10 }
11}
12
13fetchData();Sử dụng một khối try...catch cho phép bạn bắt lỗi xảy ra trong quá trình thực hiện các hoạt động bất đồng bộ, ngăn chương trình bị sập khi xảy ra lỗi.
Lợi ích của async/await
So với chuỗi Promise truyền thống, async/await mang lại những ưu điểm sau:.
- Cải thiện khả năng đọc mã
- Xử lý bất đồng bộ có thể được viết giống như mã đồng bộ, tránh được sự phức tạp của các chuỗi
Promiselồng nhau sâu và các hàm callback.
- Xử lý bất đồng bộ có thể được viết giống như mã đồng bộ, tránh được sự phức tạp của các chuỗi
- Dễ dàng gỡ lỗi hơn
- Vì nó giống với mã đồng bộ, việc gỡ lỗi và xử lý lỗi trở nên dễ dàng hơn.
- Bảo trì tốt hơn
- Các quá trình bất đồng bộ có thể được viết đơn giản hơn, giúp dễ dàng thay đổi hoặc chỉnh sửa mã và nâng cao khả năng bảo trì lâu dài.
Ví dụ: chuỗi Promise so với async/await
Hãy so sánh mã sử dụng chuỗi Promise với mã sử dụng async/await.
1// Code using Promise chains
2function fetchDataPromise() {
3 fetch('https://codesparklab.com/json/example.json')
4 .then((response) => response.json())
5 .then((data) => {
6 console.log(data);
7 })
8 .catch((error) => {
9 console.error('Failed to fetch data:', error);
10 });
11}
12
13// Code using async/await
14async function fetchDataAsync() {
15 try {
16 const response = await fetch('https://codesparklab.com/json/example.json');
17 const data = await response.json();
18 console.log(data);
19 } catch (error) {
20 console.error('Failed to fetch data:', error);
21 }
22}Như bạn có thể thấy, sử dụng async/await cho phép bạn viết các quá trình bất đồng bộ theo cách tuyến tính, dẫn đến mã dễ đọc hơn.
Thực hiện nhiều hoạt động bất đồng bộ cùng lúc
Bằng cách kết hợp Promise.all() hoặc Promise.race() với await, bạn có thể thực hiện nhiều hoạt động bất đồng bộ cùng lúc và xử lý kết quả của chúng tổng hợp.
Promise.all()
1async function fetchMultipleData() {
2 try {
3 const [data1, data2] = await Promise.all([
4 fetch('https://codesparklab.com/json/example1.json'),
5 fetch('https://codesparklab.com/json/example2.json')
6 ]);
7 const jsonData1 = await data1.json();
8 const jsonData2 = await data2.json();
9 console.log(jsonData1);
10 console.log(jsonData2);
11 } catch (error) {
12 console.error('Failed to fetch data:', error);
13 }
14}
15
16fetchMultipleData();Promise.all()giải quyết nhiều Promise cùng lúc và trả về kết quả của chúng dưới dạng một mảng. Nó chờ tất cả Promise được giải quyết, và nếu bất kỳ Promise nào thất bại, toàn bộ sẽ được xem như thất bại.
Promise.race()
1async function fetchFastestData() {
2 try {
3 const fastestResponse = await Promise.race([
4 fetch('https://codesparklab.com/json/example1.json'),
5 fetch('https://codesparklab.com/json/example2.json')
6 ]);
7 const jsonData = await fastestResponse.json();
8 console.log('Fastest data:', jsonData);
9 } catch (error) {
10 console.error('Fetch error:', error);
11 }
12}
13
14fetchFastestData();Promise.race()trả về kết quả của Promise đầu tiên được hoàn thành hoặc bị từ chối. Nó hữu ích khi bạn muốn phản hồi với bất kỳ thao tác bất đồng bộ nào hoàn thành đầu tiên. Tuy nhiên, nếu Promise đầu tiên thất bại, lỗi sẽ ngay lập tức được bắt bởicatch.
Promise.allSettled()
1async function fetchWithAllSettled() {
2 const results = await Promise.allSettled([
3 // This URL will success
4 fetch('https://codesparklab.com/json/example1.json'),
5 // This URL will fail
6 fetch('https://invalid.codesparklab.com/')
7 ]);
8
9 results.forEach((result, index) => {
10 if (result.status === 'fulfilled') {
11 const url = result.value.url;
12 console.log(`Request ${index + 1} succeeded:`, url);
13 } else {
14 const reason = result.reason;
15 console.warn(`Request ${index + 1} failed:`, reason);
16 }
17 });
18}
19
20fetchWithAllSettled();Promise.allSettled()sẽ đợi tất cả các kết quả, bất kể thành công hay thất bại. Mỗi kết quả được trả về dưới dạng{ status, value }hoặc{ status, reason }, cho phép bạn xác định Promise nào thành công và Promise nào thất bại.
Promise.any()
1async function fetchAnySuccessful() {
2 try {
3 const firstSuccessful = await Promise.any([
4 // This URL will fail
5 fetch('https://invalid.codesparklab.com/'),
6 // This URL will success
7 fetch('https://codesparklab.com/json/example1.json')
8 ]);
9 const jsonData = await firstSuccessful.json();
10 console.log('First successful response:', jsonData);
11 } catch (error) {
12 console.error('All fetch requests failed:', error);
13 }
14}
15
16fetchAnySuccessful();Promise.any()chỉ trả về kết quả của Promise hoàn thành thành công đầu tiên. Ngoại lệ chỉ được ném ra nếu tất cả các Promise đều thất bại. Nó có thể được sử dụng như một cơ chế thử lại trong môi trường mà một số API không ổn định cho đến khi một cái thành công.
Tóm tắt
- Hàm
async: Luôn trả về một Promise và được sử dụng để viết xử lý bất đồng bộ. await: Được sử dụng để chờ một Promise được giải quyết và nhận kết quả của nó.- Xử lý lỗi: Sử dụng
try...catchđể xử lý các lỗi xảy ra trong quá trình xử lý bất đồng bộ. - Nhiều thao tác bất đồng bộ: Bằng cách sử dụng các phương thức như
Promise.all(), bạn có thể chạy đồng thời nhiều tác vụ bất đồng bộ.
async/await là các công cụ mạnh mẽ để xử lý bất đồng bộ, vì vậy hãy chắc chắn tận dụng chúng để đơn giản hóa logic bất đồng bộ phức tạp.
Bạn có thể làm theo bài viết trên bằng cách sử dụng Visual Studio Code trên kênh YouTube của chúng tôi. Vui lòng ghé thăm kênh YouTube.