Skip to content

Instantly share code, notes, and snippets.

@anhtq1998
Last active April 4, 2022 14:35
Show Gist options
  • Save anhtq1998/e4aa118b5630eeb004010007013c339f to your computer and use it in GitHub Desktop.
Save anhtq1998/e4aa118b5630eeb004010007013c339f to your computer and use it in GitHub Desktop.

JavaScript Runtime

  • Javascript là ngôn ngữ lập trình đơn luồng (single-threaded). Câu hỏi đặt ra là tại sao JS lại có thể xử lý hàng nghìn câu lệnh mà không gặp 1 sự cố nào khiến đứng, treo chương trình. Đó là nhờ cơ chế của JS Runtime.

Sơ đồ bộ máy của JS Runtime alt text

Call Stack nhắc lại

  • JavaScript là ngôn ngữ single-threaded (đơn luồng). Có nghĩa là nó chỉ có một call stack đơn lẻ. Cho nên nó chỉ thực hiện duy nhất mỗi 1 tác vụ trong một lần thực thi.

  • Khi bạn bắt đầu một function, function đó sẽ được đẩy vào vùng chứa đầu tiên của stack. Rồi khi function đó kết thúc thì nó sẽ được remove ra khỏi stack. Đó là toàn bộ những gì stack có thể làm.

  • Lỗi thường gặp với stack là stack overflow. Tức là tràn stack khi mà các tiến trình cứ liên tục được push vào stack mà không pop ra sau khi thực hiện xong dẫn đến tràn bộ nhớ stack. Lỗi này thường gặp khi sử dụng đệ quy không cẩn thận và bộ nhớ stack là có hạn.

Javascript là ngôn ngữ đơn luồng vậy nó sẽ xử lý sao khi gặp Deadlock.

Deadlock

  • Deadlock (Khóa chết) là trạng thái xảy ra trong môi trường đa nhiệm (muti-threading) khi hai hoặc nhiều tiến trình đi vào vòng lặp chờ tài nguyên mãi mãi.

Web APIs.

  • được build trong browser của bạn, đó là những APIs của trình duyệt, chứ không phải của Javascript như Mouse Event, setTimeout, XMLHttpRequest, Geolocation,…

  • Chúng là những thread mà bạn không thể truy cập được, chỉ có thể gọi để xài mà thôi. Chúng là những nhân tố trong trình duyệt mà thực sự có thể chạy đồng thời (concurrency).

  • Bản chất Runtime của Javascript chỉ có 1 luồng và không thể chạy multi-thread, vì thế browser đã viết thêm một Web APIs để bọc runtime này lại (tương tự dưới NodeJS sẽ dùng C++ để bọc V8 lại). Web APIs này sẽ giúp cho JS có thể hoạt động một cách bất đồng bộ như multi-thread.

Callback Queue

  • Là hàng đợi các callback do thằng Web APIs ở trên trả về.
  • Là cấu trúc dữ liệu chứa các hàm async callback.
  • tất cả cá event được push vào Queue này, mỗi khi một sự kiện được phát ra từ thằng webapis nó sẽ được push vào Queue. Trong Queue này, thứ tự thực hiện là vào trước thì sẽ được xử lí trước, vào sau thì được xử lí sau.(FIFO)

Event Loop

  • Event Loop có một nhiệm vụ rất đơn giản đó là quan sát Call StackCallback Queue nếu Call Stack rỗng thì sẽ lấy hàm đầu tiên trong queue và đẩy nó vào trong Call Stack để thực thi.

Alt Text

Ví dụ

$.on('button', 'click', function onClick() {
    setTimeout(function timer() {
        console.log('You clicked the button!');    
    }, 2000);
});

console.log("Hi!");

setTimeout(function timeout() {
    console.log("Click the button!");
}, 5000);

console.log("Welcome to loupe.");
//output: Hi, Dyno, Bat Dong Bo, Event Loop

Các bước hoạt động Alt Text

  1. Bước 1:
$.on('button', 'click', function onClick() {
    setTimeout(function timer() {
        console.log('You clicked the button!');    
    }, 2000);
});

Hàm này chạy vào stack. Stack nhận ra nó là 1 webAPIS nên đẩy sang Webapis.

  1. Bước 2.
console.log("Hi!");

console.log đi vào stack được thực hiện và pop ra luôn khỏi call stack.

  1. Bước 3:
setTimeout(function timeout() {
    console.log("Click the button!");
}, 5000);

Hàm này chạy vào stack và đc chuyển tiếp sang WebApis để chạy timer.

  1. Bước 4
console.log("Welcome to loupe.");

lệnh console.log tiếp tục được push vào stack để thực hiện sau đó đc lấy ra sau khi thực hiện xong. Trong cùng thời gian này timer() của hàm setTimeout bên trên cũng đang chạy timer();

  1. Bước 5: sau khi hết timer của setTimeOut() thì WebApis sẽ bắn 1 callback vào hàng đợi queue.

  2. Bước 6: Lúc này Event loop quan sát call stack và nhận thấy call stack đang rỗng nên event loop đã cho phép callback ở callback queue được phép push vào call stack để thực hiện.

  3. Bước 7

console.log("Click the button!");

lúc này lệnh console.log này được push vào call stack và sau khi thực hiện xong sẽ bị đẩy ra khỏi call stack.

  • Nếu người dùng tiếp tục click vào button thì webapis lại tiếp tục bắn sang queue 1 callback function và event loop lại tiếp tục làm việc khi thấy call stack mà rỗng sẽ lấy ra cb ở callback queue để push vào stack thực hiện.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment