Event loop
Posted: Tuesday, 8 November 2022 at 13:24
Updated: Tuesday, 8 November 2022 at 13:24

Event Loop là gì?

Event Loop là cơ chế giúp Javascript có thể thực hiện nhiều thao tác cùng một lúc (concurrent model), trước giờ vẫn nghe nói NodeJs có thể xử lý cả hàng ngàn request cùng một lúc mặc dù nó chỉ dùng một thread duy nhất (Single Threaded). Nếu như ở PHP hay Java thì với mỗi một request sẽ sinh ra một thread để xử lý request đó, các thread hoạt động độc lập, được cấp bộ nhớ, giao tiếp ngoại vi và trả về kết quả. Vậy làm thế nào để NodeJs có thể xử lý cả ngàn request một lúc với chỉ một thread duy nhất?.

Có một sự thật là trên web browser thì trong khi get data từ các url thì người dùng vẫn có thể thực hiện các thao tác khác như click button và gõ vào các ô textbox. Tất cả là nhờ có các web apis và cơ chế hoạt động của Event Loop. Tuy Js Runtime chỉ có một thread duy nhất nhưng các web apis giúp nó giao tiếp với thế giới multi thread bên ngoài, tận dụng các con chip đa nhân vốn rất phổ biến hiện nay. Web apis giúp đẩy các job ra bên ngoài và chỉ tạo ra các sự kiện kèm theo các handler gắn với các sự kiện. Kể cả đối với NodeJs khi không có web apis thì nó vẫn có các cơ chế tương đương khác giúp đẩy job ra bên ngoài và chỉ quản lý các đầu việc. Web Apis hoạt động như vậy thì Event Loop sẽ thế nào ?

Event Loop hoạt động như thế nào?

Event Loop có tên như vậy bởi vì có một vòng lặp vô tận trong Javascript Runtime (V8 trong Google Chrome) dùng để lắng nghe các Event.

while (queue.waitForMessage()) {
queue.processNextMessage();
}

Nhiệm vụ của Event Loop rất đơn giản đó là đọc Stack và Event Queue. Nếu nhận thấy Stack rỗng nó sẽ nhặt Event đầu tiên trong Event Queue và handler (callback hoặc listener) gắn với Event đó và đẩy vào Stack. Đặc điểm của việc thực thi hàm trong JS là sẽ chỉ dừng lại khi hàm return hoặc throw exception. Có nghĩa là trong khi hàm đang chạy thì sẽ không có một hàm khác được chạy, dữ liệu tạm của hàm cũng sẽ không bị thay đổi bởi một hàm khác hay cũng không bị dừng lại cho đến khi hoàn thành (ngoại trừ yield trong ES6).

Như các bạn thấy trên hình thì JS Runtime còn thao tác với một callback queue hay event queue ngoài stack ra. Event queue này khác với stack ở chỗ nó là queue kiểu FIFO (First In First Out). Mỗi khi có một Event được tạo ra, ví dụ user click vào một Button thì một Event sẽ được đẩy vào Event queue cùng với một handler (event listener) gắn với nó. Nếu một Event không có listener thì nó sẽ bị mất và không được đẩy vào Event queue. Để cho dễ hình dung cách thức hoạt động của Event Loop ta lấy một ví dụ như sau:

const fs =require('fs'); 
function someAsyncOperation(callback){
// giả sử đọc file hết 95ms
fs.readFile('/path/to/file', callback);
}

const timeoutScheduled =Date.now();

setTimeout(function logInfo()=>{
const delay = Date.now()- timeoutScheduled;
console.log(`${delay}ms have passed since I was scheduled`);
},100); 

// đọc file xong sẽ tiếp tục chờ thêm 10ms
someAsyncOperation(function readFileAsync()=>{
const startCallback = Date.now();
// chờ 10ms
while(Date.now()- startCallback <10){
// do nothing
}
});

Find an issue with this page? Fix it on GitHub

Need help? Email mooncomvn130@gmail

Copyright © 2022 Fireship LLC