Asynchronous JavaScript là gì?

Asynchronous JavaScript là cách JavaScript xử lý các tác vụ không đồng bộ, cho phép chương trình tiếp tục thực thi các đoạn mã khác mà không bị chặn bởi các tác vụ tốn thời gian, như gọi API, truy vấn cơ sở dữ liệu, hoặc đọc/ghi file.

JavaScript sử dụng mô hình bất đồng bộ để xử lý các tác vụ này nhằm tăng hiệu quả và không làm ngưng trệ ứng dụng.

Mô hình hoạt động:

JavaScript sử dụng một kiến trúc gọi là Event Loop để quản lý tác vụ đồng bộ và bất đồng bộ:

  1. Call Stack (Ngăn xếp thực thi): Nơi JavaScript thực thi các tác vụ đồng bộ.
  2. Web APIs: Chứa các tác vụ bất đồng bộ, như setTimeout, xử lý sự kiện DOM, hoặc HTTP requests.
  3. Task Queue: Khi một tác vụ bất đồng bộ hoàn thành, nó được đẩy vào hàng đợi để chờ thực thi.
  4. Event Loop: Liên tục kiểm tra Call Stack và Task Queue để quyết định khi nào đẩy các tác vụ từ Task Queue vào Call Stack.

Cách xử lý bất đồng bộ trong JavaScript:

Có ba cách chính để xử lý bất đồng bộ:

1. Callbacks:

  • Là cách phổ biến và lâu đời nhất để xử lý bất đồng bộ.
  • Một hàm được truyền vào và được gọi khi tác vụ hoàn thành.

Ví dụ:

Ví dụ :
console.log('Start');
 
setTimeout(() => {
    console.log('This is async');
}, 2000);
 
console.log('End');
Ví dụ :
Start
End
This is async

2. Promises:

  • Promises là một cơ chế hiện đại hơn để xử lý bất đồng bộ, giúp cải thiện vấn đề callback hell.
  • Một Promise có thể ở ba trạng thái:
    • Pending (Đang chờ): Tác vụ chưa hoàn thành.
    • Resolved (Hoàn thành): Tác vụ thành công.
    • Rejected (Thất bại): Tác vụ gặp lỗi.
Ví dụ :
const fetchData = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve("Data received");
    }, 2000);
});
 
fetchData
    .then(data => console.log(data)) // "Data received"
    .catch(error => console.error(error));

3. Async/Await:

  • Cung cấp cú pháp dễ đọc và viết hơn khi làm việc với Promises.
  • Từ khóa async biến một hàm thành bất đồng bộ, và await được dùng để chờ một Promise hoàn thành trước khi tiếp tục.
Ví dụ :
async function fetchData() {
    console.log('Fetching...');
    const data = await new Promise(resolve => setTimeout(() => resolve('Data received'), 2000));
    console.log(data);
}
 
fetchData();

Các tình huống sử dụng Asynchronous JavaScript:

  1. Gọi API: Lấy dữ liệu từ server bằng fetch hoặc axios.
  2. Xử lý sự kiện: Đăng ký các sự kiện như click, keydown.
  3. Đọc/Ghi File: Làm việc với hệ thống file qua Node.js.
  4. Thao tác thời gian: Sử dụng setTimeout hoặc setInterval để thực thi sau một khoảng thời gian.

Ưu điểm của Asynchronous JavaScript:

  1. Hiệu quả cao: JavaScript có thể thực hiện nhiều tác vụ đồng thời mà không chặn chương trình.
  2. Trải nghiệm người dùng tốt: Giao diện không bị đơ khi chờ tác vụ hoàn thành.

Nhược điểm:

  1. Callback Hell: Nếu không quản lý tốt các callback, mã trở nên khó đọc.
  2. Debug khó khăn: Xử lý lỗi trong mã bất đồng bộ phức tạp hơn.

Tóm lại:

Asynchronous JavaScript là nền tảng để xây dựng các ứng dụng web hiện đại, nơi tốc độ và khả năng xử lý tác vụ đồng thời là yếu tố quan trọng. Nó hoạt động thông qua callbacks, promises, và async/await, giúp xử lý các tác vụ dài mà không làm gián đoạn luồng chính của chương trình.