Async/Await là gì? Cú pháp khai báo và ví dụ Async/Await trong Javascript
05/05/2026Khi xử lý bất đồng bộ, việc sử dụng callback hay Promise đôi khi khiến code trở nên khó đọc và khó kiểm soát. Async/await ra đời như một cách viết đơn giản hơn, giúp luồng xử lý rõ ràng và trực quan hơn. Cùng Viettel IDC tìm hiểu async/await là gì, cú pháp khai báo và ví dụ minh hoạ trong JS.
Async/Await là gì?
Async/await là cú pháp được sử dụng để xử lý các tác vụ bất đồng bộ một cách dễ hiểu và trực quan hơn. Thay vì phải sử dụng callback hoặc Promise chaining phức tạp, async/await giúp code trông giống như đang chạy tuần tự, từ đó cải thiện đáng kể khả năng đọc và bảo trì. Cơ chế này vẫn dựa trên Promise, nhưng cách viết gọn gàng và rõ ràng hơn rất nhiều, đặc biệt phù hợp với các luồng xử lý dữ liệu như gọi API hoặc xử lý nhiều bước liên tiếp.
Các thành phần chính:
- async: dùng để khai báo một hàm theo cơ chế bất đồng bộ. Khi một hàm có từ khóa này, nó sẽ luôn trả về một Promise, kể cả khi bạn return một giá trị thông thường.
- await: dùng để chờ một Promise hoàn thành và trả về kết quả. Khi gặp await, chương trình sẽ tạm dừng thực thi trong phạm vi hàm async cho đến khi Promise resolve hoặc reject, sau đó mới tiếp tục chạy các dòng code phía sau.
Cơ chế hoạt động của Async/await là gì?
Async/await hoạt động dựa trên Promise và cơ chế xử lý bất đồng bộ của JavaScript. Khi một hàm được khai báo với async, kết quả trả về của hàm đó luôn được đóng gói dưới dạng Promise. Trong quá trình thực thi, nếu JavaScript gặp từ khóa await, nó sẽ tạm ngưng phần xử lý bên trong hàm async để chờ Promise hoàn tất. Sau khi Promise trả về kết quả thành công hoặc phát sinh lỗi, chương trình sẽ tiếp tục chạy các câu lệnh còn lại trong hàm.
Cách hoạt động của async/await có thể được hiểu theo trình tự sau:
- Hàm async được gọi → Trả về một Promise
- Khi gặp await → Tạm dừng trong phạm vi hàm đó
- JavaScript tiếp tục xử lý các tác vụ khác trong event loop
- Khi Promise hoàn thành → Quay lại thực thi tiếp phần còn lại của hàm
Vì sao cần async/await?
Async/await được sử dụng rộng rãi, giúp việc xử lý bất đồng bộ trong JavaScript trở nên đơn giản, rõ ràng và dễ kiểm soát hơn so với các phương pháp truyền thống. Nhờ cú pháp trực quan và cách hoạt động gần giống với code đồng bộ, async/await mang lại nhiều lợi ích quan trọng trong quá trình phát triển ứng dụng:
- Code dễ đọc, dễ hiểu: Thay vì lồng ghép nhiều hàm .then(), bạn có thể viết code theo trình tự tuyến tính, giúp người đọc dễ theo dõi luồng xử lý dữ liệu.
- Tránh Callback Hell: Giải quyết vấn đề code bị lồng nhau quá nhiều tầng, giúp cấu trúc chương trình sạch sẽ hơn.
- Xử lý lỗi đơn giản: Bạn có thể sử dụng cú pháp try/catch truyền thống để bắt lỗi từ các tác vụ bất đồng bộ, giống như cách làm với code đồng bộ.
- Xử lý bất đồng bộ hiệu quả: Tạm dừng thực thi hàm (await) cho đến khi Promise trả về kết quả, nhưng không làm chặn (block) luồng chính (main thread) của chương trình.
- Phổ biến trong các tác vụ thực tế: Đặc biệt hữu ích khi cần gọi API lấy dữ liệu, thao tác cơ sở dữ liệu hoặc xử lý tệp tin.
Cú pháp khai báo async/await là gì?
Cú pháp async/await trong JavaScript dùng để xử lý bất đồng bộ, giúp mã nguồn dễ đọc hơn. Từ khóa async đặt trước hàm để biến nó thành hàm bất đồng bộ trả về Promise. Từ khóa await (chỉ dùng trong hàm async) dừng thực thi để chờ kết quả Promise.
Khai báo hàm với async
Để định nghĩa một hàm bất đồng bộ, bạn thêm từ khóa async phía trước hàm. Khi đó, bất kể bên trong hàm trả về giá trị gì, JavaScript cũng sẽ tự động chuyển nó thành một Promise. Nhờ vậy, hàm async luôn có thể kết hợp với các thao tác bất đồng bộ khác.
Hàm getData() không trả về trực tiếp chuỗi mà trả về một Promise chứa giá trị đó. Khi gọi hàm, bạn có thể dùng .then() hoặc await để lấy kết quả.
Sử dụng await để chờ kết quả
Từ khóa await chỉ có thể sử dụng bên trong hàm async và được dùng để chờ một Promise hoàn thành. Khi chương trình gặp await, nó sẽ tạm dừng việc thực thi tại dòng đó cho đến khi Promise trả về kết quả, sau đó mới tiếp tục chạy các câu lệnh phía sau.
Giá trị trả về từ getData() sẽ được gán vào biến result sau khi Promise hoàn thành. Luồng xử lý diễn ra theo thứ tự từ trên xuống nên dễ đọc và dễ kiểm soát hơn.
Kết hợp try/catch khi xử lý lỗi
Khi làm việc với async/await, việc xử lý lỗi thường được thực hiện bằng khối try/catch. Cách này giúp bắt cả lỗi đồng bộ và bất đồng bộ trong cùng một cấu trúc.
Nếu Promise bị reject hoặc có lỗi trong quá trình xử lý dữ liệu, chương trình sẽ chuyển sang khối catch. Nhờ đó, lỗi được kiểm soát rõ ràng và không làm gián đoạn toàn bộ ứng dụng.
Ví dụ async/await trong javascript dễ hiểu
Để hiểu rõ hơn, hãy xét một tình huống thực tế: Bạn cần lấy thông tin người dùng từ API, sau đó dùng userId để lấy danh sách bài viết của người đó.
- Với Promise và .then()
- Với async/await
Trong hai ví dụ trên, cả Promise và async/await đều xử lý cùng một luồng logic, tuy nhiên cách thể hiện có sự khác biệt rõ rệt. Với Promise, code được viết theo kiểu chaining các hàm .then(), trong khi async/await cho phép viết theo trình tự từ trên xuống giống như code đồng bộ. Luồng xử lý trở nên trực quan hơn, dễ đọc hơn và thuận tiện hơn khi mở rộng hoặc bảo trì trong các bài toán thực tế có nhiều bước xử lý liên tiếp.
So sánh async/await vs promise vs callback
Trong JavaScript, xử lý bất đồng bộ đã trải qua nhiều giai đoạn phát triển, từ callback đến Promise và sau đó là async/await. Mỗi cách đều có đặc điểm riêng, nhưng async/await được xem là cách viết hiện đại và tối ưu nhất hiện nay.
Lỗi thường gặp khi dùng async/await và cách khắc phục nhanh
Khi sử dụng async/await, lập trình viên thường gặp một số lỗi phổ biến liên quan đến cách dùng cú pháp và hiểu sai cơ chế hoạt động. Những lỗi này có thể khiến code không chạy đúng như mong muốn hoặc gây khó khăn trong quá trình debug.
Quên sử dụng await
Một lỗi phổ biến là gọi hàm trả về Promise nhưng không dùng await, dẫn đến việc nhận về Promise thay vì dữ liệu thực tế.
Trong trường hợp này, biến data sẽ là một Promise thay vì giá trị "Hello". Khi thêm await, chương trình mới trả về đúng dữ liệu mong muốn.
Dùng await ngoài hàm async
Await chỉ hoạt động bên trong hàm được khai báo với async. Trong trường hợp dùng await bên ngoài hàm async, JavaScript sẽ phát sinh lỗi vì cú pháp này chỉ hợp lệ khi nằm trong một hàm bất đồng bộ.
Để khắc phục, cần đặt đoạn code này bên trong một hàm async hoặc sử dụng .then() thay thế.
Không xử lý lỗi với try/catch
Khi Promise bị reject mà không có xử lý lỗi, ứng dụng có thể bị crash hoặc gây ra lỗi không kiểm soát.
Nếu fetchData() xảy ra lỗi, chương trình sẽ dừng đột ngột. Việc sử dụng try/catch giúp kiểm soát và xử lý lỗi rõ ràng hơn.
Chạy tuần tự không cần thiết
Nhiều trường hợp các Promise không phụ thuộc nhau nhưng vẫn được viết theo kiểu tuần tự, làm giảm hiệu năng.
Nếu hai hàm không liên quan, có thể chạy song song để tối ưu thời gian bằng Promise.all().
Hiểu sai await là đồng bộ hoàn toàn
Một số người cho rằng await làm chương trình chạy đồng bộ hoàn toàn, nhưng thực tế chỉ tạm dừng trong phạm vi hàm async.
Trong thời gian chờ, JavaScript vẫn tiếp tục xử lý các tác vụ khác trong event loop. Code vẫn mang bản chất bất đồng bộ, chỉ là cách viết trở nên tuần tự hơn.
Kết luận
Async/Await là gì là kiến thức nền tảng khi làm việc với JavaScript. Khi nắm rõ cơ chế và cách sử dụng, bạn có thể tổ chức luồng xử lý logic một cách mạch lạc, dễ đọc và hạn chế lỗi. Kết hợp linh hoạt với Promise sẽ giúp tối ưu hiệu năng và nâng cao chất lượng code trong các bài toán như gọi API, xử lý dữ liệu hay phát triển ứng dụng web.
Để được hỗ trợ tư vấn và tìm hiểu các dịch vụ của Viettel, bạn có thể liên hệ trực tiếp tới Viettel IDC qua các kênh:
- Hotline: 1800 8088 (miễn phí cước gọi)
- Fanpage: https://www.facebook.com/viettelidc
Tin liên quan
Lỗi msvcr100.dll là gì? Hướng dẫn cách sửa lỗi msvcr100 dll nhanh chóng
Lỗi msvcr100.dll khiến phần mềm không khởi chạy trên Windows. Xem hướng dẫn khắc phục từng bước để bổ sung thư viện còn thiếu và sửa chữa chương trình bị lỗi.
Top 20 các extension visual studio code hữu ích cho lập trình viên
Các extension Visual Studio Code hữu ích mở rộng khả năng của trình soạn thảo, giúp lập trình viên tối ưu môi trường làm việc và nâng cao hiệu quả viết mã.
Bridge là gì? Cách hoạt động và ứng dụng trong mạng LAN
Bridge là gì? Cầu nối mạng hoạt động dựa trên địa chỉ MAC để kết nối các phân đoạn LAN, kiểm soát luồng dữ liệu và hỗ trợ triển khai mạng vật lý lẫn mạng ảo.
Lỗi Blocked due to other 4xx issue là gì? Nguyên nhân và cách fix lỗi
Lỗi Blocked due to other 4xx issue khiến Google không lập chỉ mục URL, cần xác định đúng mã HTTP và nguyên nhân để khắc phục hiệu quả trong Search Console.
Test case là gì? Cách viết test case và mẫu minh họa cho người mới
Test case là gì và làm sao để viết rõ ràng, đúng yêu cầu? Nắm vững cách xây dựng trường hợp kiểm thử qua ví dụ cụ thể để phát hiện sai lệch trong hoạt động phần mềm.
AI Inference là gì? Cơ chế và vai trò trong vận hành AI
AI inference là gì? Cách mô hình AI tạo kết quả sau huấn luyện, phân biệt với AI training, các hình thức triển khai và ứng dụng thực tế trong doanh nghiệp.
DBeaver là gì? Hướng dẫn cài đặt và kết nối cơ sở dữ liệu với DBeaver
DBeaver là gì? Khám phá tính năng quản lý cơ sở dữ liệu, các phiên bản miễn phí và trả phí cùng hướng dẫn cài đặt, kết nối, chạy truy vấn SQL cho người mới.
Cách thay đổi mật khẩu máy tính trên Windows 10, 11 đơn giản
Cách thay đổi mật khẩu máy tính trên Windows 10, 11 qua Settings, Control Panel, CMD và các công cụ quản trị được hướng dẫn chi tiết theo từng bước dễ thực hiện.
Microsoft Management Console là gì? Cách sử dụng MMC cho người mới
Microsoft Management Console là gì? Đây là nền tảng tập hợp các công cụ quản trị Windows, hỗ trợ quản lý hệ thống, thêm snap-in và lưu console theo nhu cầu sử dụng.
Rủi ro khi sử dụng giả lập online và cách phòng tránh
Rủi ro khi sử dụng giả lập online có thể gây lộ dữ liệu, mất quyền kiểm soát tài khoản, lừa đảo trực tuyến, vi phạm chính sách game, gián đoạn thao tác và phát sinh chi phí.
Bình luận ()