Cách Event Loop quản lý các tác vụ bất đồng bộ trong Javascript

0 0 0

Người đăng: Thành Nguyễn Văn

Theo Viblo Asia

Mở đầu

  • JavaScript là một ngữ lập trình chạy đơn luồng - single-threaded !!! Nếu vậy không phải một tác vụ chạy quá lâu thì sẽ ngăn chặn các tác vụ phía sau gây nên tình trạng trang web bị treo! 🤔
  • Nhưng thực chất khi truy cập, tương tác với các website trên trình duyệt chúng ta vẫn thấy mọi thứ được xử lý rất mượt mà!
  • Vậy phải có một cơ chế độc đáo để quản lý các tác vụ này mà không gây tắc nghẽn hệ thống?!
  • Đó chính là lúc Event Loop xuất hiện và làm chủ cuộc chơi 😎.

Event Loop là gì?

  • Event Loop là một thành phần của Javascript Runtime Environment (môi trường thực thi Javascript).
  • Event Loop giúp quản lý, thực thi các tác vụ một cách bất đồng bộ mà không lo việc phải chờ đợi lẫn nhau.
  • Chúng ta hãy cùng tìm hiểu chi tiết hơn về Javascript Runtime Environment, cách thức hoạt động và vai trò của Event Loop trong hệ thống này như thế nào nhé !

JavaScript Runtime Environment

  • JavaScript Runtime Environment là nơi để xử lý và thực thi các tác vụ liên quan đến JavaScript.
  • Để JavaScript có thể thực thi một cách mượt mà thì cần đến các thành phần chính sau:
Sơ đồ mô tả luồng thực thi Javascript và các thành phần của Javascript Runtime Enviroment

1. JavaScript Engine

  • Tất nhiên điều quan trọng tiên quyết là chúng ta phải có một trình biên dịch để dịch mã JavaScript thành mã nhị phân để máy tính có thể hiểu và thực thi.
  • Bạn có thể tìm hiểu chi tiết hơn trong bài viết sau để hiểu rõ hơn về cấu tạo của JavaScript Engine: V8 Engine trong Chrome và Node.js
  • Nhưng JavaScript Engine chỉ có thể xử lý được các đoạn mã thuần và chạy một cách đồng bộ (chạy theo nguyên lý hàng đợi Stack).
js // Javascript Engine chỉ có thể xử lý các đoạn mã Javascript thuần như: // ghi log
console.log("Learning Javascript"); // khai báo biến
const a = 1
  • Để có thể xử lý được các đoạn mã phức tạp hơn như: kết nối đến giao thức Http, quản lý các tác vụ bất đồng bộ, các sự kiện để tác động đến DOM, CSDOM tree,... thì lúc này chúng ta cần sự hỗ trợ thêm của các thành phần khác.

2. Web / Browser Api

  • Web / Browser Api là các API cung cấp bởi Runtime Environment (Browser, Node.Js).
  • API (Application Programming Interface) chính là công cụ để Javascript có thể giao tiếp được với môi trường bên ngoài !

2.1. DOM

  • DOM (Document Object Model) là một tập hợp các phương thức giúp JavaScript giao tiếp, tương tác với HTML/CSS.
  • Các phương thức này được thực thi một cách đồng bộ (synchoronous).
js // Tạo nội dụng HTML cho phần tử với id="mydiv"
document.getElementById("mydiv").innerHTML = "Hello Viblo!!!"; // Đổi màu chữ thành màu xanh dương cho phần tử với id="mydiv"
document.getElementById("mydiv").style.color = "blue"; 

2.2. Web Storage Api

  • Web Storage API giúp lưu trữ dữ liệu trên trình duyệt của người dùng theo hai dạng chính:
Loại Chức năng
localStorage Lưu dữ liệu vĩnh viễn, không bị mất khi đóng trình duyệt.
sessionStorage Lưu dữ liệu tạm thời, bị mất khi đóng tab trình duyệt.
js // localStorage
localStorage.setItem("username", "ThanhEtn");
localStorage.getItem("username"); // sessionStorage
sessionStorage.setItem("token", "abc123");
sessionStorage.getItem("token");

2.3. Web Worker Api

  • Web Worker giúp xử lý công việc nặng trên background thread (một thread riêng biệt chạy trong nền), giữ cho main thread (UI) không bị chặn.
  • Một số tác vụ mà Web Worker có thể xử lý một cách hiệu quả:
Tác vụ Mô tả
Xử lý tính toán phức tạp Xử lý dữ liệu lớn, tính toán số nguyên tố
Xử lý dữ liệu lớn Parse file JSON lớn, xử lý dữ liệu log, thống kê số liệu
Gọi API & Xử lý dữ liệu Fetch, WebSockets, IndexedDB, Timer API
Nén & Giải nén dữ liệu Nén ảnh, video, file trước khi gửi đi
js // Gửi yêu cầu Https đến server
async function getData () { const response = await fetch("https://viblo.asia/api/posts/newest?limit=20"); return await response.json();
} // SetTimeOut - Timer API
console.log("Chạy trong Main Thread");
setTimeout(() => { console.log("Đã chờ 3 giây trong Web Worker!");
}, 3000);
  • Vậy khi các tác vụ này đã được thực thi xong trong Web Worker thì thành phần nào sẽ đưa chúng trở lại Call Stack để thực thi 🤔?

3. Task Queue / MicroTask Queue

  • Các tác vụ bất đồng bộ (asynchoronous) sau khi đã thực thi xong trong Web Worker sẽ được đưa vào các hàng đợi đặt biệt là: Task Queue, MicroTask Queue.
  • Các hàng đợi (Queue) này được thực thi theo quy tắc: FIFO (First In, First Out). Tức là tác vụ nào được đưa vào hàng đợi trước sẽ được thực thi trước.
js // Task 1 vào hàng đợi trước Task 2, nên nó sẽ được thực thi trước
setTimeout(() => console.log("Task 1"), 0);
setTimeout(() => console.log("Task 2"), 0);
  • MicroTask Queue có thứ tự ưu tiên cao hơn so với Task Queue. Các tác vụ trong MicroTask Queue sẽ được thi đến khi nào rỗng thì mới tới các tác vụ trong Task Queueđược thực thi.
js console.log("Start");
setTimeout(() => console.log("Task Queue"), 0);
Promise.resolve().then(() => console.log("MicroTask Queue"));
console.log("End");
Trình tự thực thi
1. "Start" → Call Stack (thực thi ngay)
2. setTimeout() → Gửi vào Task Queue
3. Promise.then() → Gửi vào MicroTask Queue
4. "End" → Call Stack (thực thi ngay)
5. MicroTask Queue chạy trước → "MicroTask Queue"
6. Sau khi MicroTask Queue trống → "Task Queue" được thực thi.
  • Nhưng CallStack có phải lúc nào cũng trong trạng thái sẵn sàng để các tác vụ trong Queue có thể được đưa vào thực thi?

4. Event Loop

  • Event Loop chính là chiếc cầu nối giữa Call Stack với Task Queue, MicroTask Queue. Giúp đảm bảo các tác vụ bất đồng bộ xử lý một cách mượt mà dù Javascript chỉ chạy 1 luồng duy nhất 😎💯.
  • Các nhiệm vụ chính mà Event Loop thực hiện đó là:
  1. Kiểm tra trạng thái của Call Stack nếu trống sẽ tìm một tác vụ mới từ Queue để đẩy vào Call Stack thực thi.
  2. Ưu tiên lấy tác vụ từ MicroTask Queue trước. Xử lý từng tác vụ trong đây và đưa vào Call Stack để thực thi.
  3. Khi MicroTask Queue đã rỗng. Lấy từng tác vụ trong Task Queue đưa vào Call Stack để thực thi.
Sơ đồ mô tả cách Event Loop hoạt động

Kết luận

  • Javascript một ngôn ngữ chạy đơn luồng nhưng với một kiến trúc tuyệt vời của Javascript Runtime Enviroment đã có thể xử lý một cách mượt mà các tác vụ, tạo ra một trải nghiệm tuyệt vời cho người dùng.
  • Nhờ vào sự kết hợp vô cùng ăn ý giữa các thành phần. Đặc biệt trong đó là Event Loop giúp điều phối sự hoạt động của các tác vụ đồng bộ và bất đồng bộ với nhau.
  • Hy vọng qua bài viết, giúp các bạn có một cái nhìn chi tiết về cách thức Javascript được thực thi cũng như giải đáp được thắc mắc ở đầu bài viết về ngôn ngữ đơn luồng lại có thể xử lý được các tác vụ bất đồng bộ 🤩.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Giới thiệu Typescript - Sự khác nhau giữa Typescript và Javascript

Typescript là gì. TypeScript là một ngôn ngữ giúp cung cấp quy mô lớn hơn so với JavaScript.

0 0 531

- vừa được xem lúc

Bạn đã biết các tips này khi làm việc với chuỗi trong JavaScript chưa ?

Hi xin chào các bạn, tiếp tục chuỗi chủ đề về cái thằng JavaScript này, hôm nay mình sẽ giới thiệu cho các bạn một số thủ thuật hay ho khi làm việc với chuỗi trong JavaScript có thể bạn đã hoặc chưa từng dùng. Cụ thể như nào thì hãy cùng mình tìm hiểu trong bài viết này nhé (go).

0 0 441

- vừa được xem lúc

Một số phương thức với object trong Javascript

Trong Javascript có hỗ trợ các loại dữ liệu cơ bản là giống với hầu hết những ngôn ngữ lập trình khác. Bài viết này mình sẽ giới thiệu về Object và một số phương thức thường dùng với nó.

0 0 162

- vừa được xem lúc

Tìm hiểu về thư viện axios

Giới thiệu. Axios là gì? Axios là một thư viện HTTP Client dựa trên Promise.

0 0 149

- vừa được xem lúc

Imports và Exports trong JavaScript ES6

. Giới thiệu. ES6 cung cấp cho chúng ta import (nhập), export (xuất) các functions, biến từ module này sang module khác và sử dụng nó trong các file khác.

0 0 114

- vừa được xem lúc

Bài toán đọc số thành chữ (phần 2) - Hoàn chỉnh chương trình dưới 100 dòng code

Tiếp tục bài viết còn dang dở ở phần trước Phân tích bài toán đọc số thành chữ (phần 1) - Phân tích đề và những mảnh ghép đầu tiên. Bạn nào chưa đọc thì có thể xem ở link trên trước nhé.

0 0 256