Lập trình không đồng bộ # 1-JS Engine - Khối bộ nhớ & Ngăn xếp cuộc gọi

Có một thành phần lớn trong JavaScript biên dịch và chạy mã của chúng tôi. Chúng tôi gọi thành phần này là công cụ JavaScript . Các công cụ JavaScript phổ biến; V8 được sử dụng bởi Google Chrome và Node.js, SpiderMonkey dành cho Firefox và JavaScriptCore được sử dụng bởi Safari / Webkit.
Công cụ JavaScript có một số thành phần làm việc chăm chỉ cho chúng tôi. Các thành phần này là; Chính Call Stack làm cho mã chúng ta viết bằng Memory Heap hoạt động . Tôi sẽ nói về các thành phần này trong bài viết này.

Bộ nhớ Heap
JavaScript là một ngôn ngữ được biên dịch và thông dịch đồng thời. Chúng tôi gọi cấu trúc hoàn hảo này là JIT (Biên dịch đúng lúc). JIT là một chủ đề toàn diện như vậy, không thể đề cập đến cách thức hoạt động của JIT trong bài viết này. Do đó, hiện tại, chúng tôi chuyển quá trình đằng sau quá trình biên dịch mã và chuyển sang giai đoạn thực thi mã của chúng tôi.
Hãy bắt đầu với đoạn mã sau:
const num = 5;
function multiply(x, y) {
return x * y;
}
function printSquare(x) {
const z = multiply(x, x);
console.log(z);
}
Quan niệm sai lầm lớn nhất là máy quét đọc và thực thi mã. Trình duyệt không làm gì với đoạn mã này. Đó là công cụ JS thực hiện công việc ở đây .
JS Engine bắt đầu đọc mã, ngay khi gặp dòng đầu tiên, nó sẽ đưa các tham chiếu có liên quan vào Heap bộ nhớ (Global Memory).
MemoryHeap ; Đây là khu vực lưu giữ các biến và định nghĩa hàm. Nếu chúng ta quay lại ví dụ của mình, công cụ sẽ lấp đầy đống bộ nhớ như sau sau khi đọc mã.

Nếu bạn biết, chúng tôi vẫn chưa chạy mã của mình. Bây giờ hãy chạy hàm của chúng ta:
const num = 5;
function multiply(x, y) {
return x * y;
}
function printSquare(x) {
const z = multiply(x, x);
console.log(z);
}
printSquare(5);
Ngăn xếp cuộc gọi
Call Stack theo dõi chức năng nào đang chạy trong nó và chức năng nào được gọi bên trong chức năng đó. Vì vậy, về cơ bản nó là một cấu trúc dữ liệu ghi lại vị trí của chúng ta trong chương trình.
Các phần tử được xếp chồng lên nhau trong một ngăn xếp, vì vậy một phần tử chức năng mới sẽ đi vào ngăn xếp từ trên cùng. Mỗi mục nhập mới được gọi là Khung xếp chồng . Và lần lượt , chúng rời khỏi Call Stack một cách đồng bộ từ trên xuống dưới .
JavaScript là một ngôn ngữ lập trình đơn luồng. Vì vậy, nó có một Ngăn xếp Cuộc gọi duy nhất. Do đó, có thể thực hiện một thao tác tại một thời điểm. Do đó, sau khi các chức năng được thực thi, chúng không thể rời khỏi Ngăn xếp Cuộc gọi nếu có một chức năng khác đang được thực hiện.
Quay trở lại ví dụ của chúng ta, hãy kiểm tra điều gì xảy ra trong Call Stack sau khi gọi hàm printSquare () ;

Tóm lại, Call Stack là một cấu trúc trong đó các giao dịch được xếp chồng lên nhau và chạy rất nhanh theo một thứ tự đồng bộ. Vậy điều gì sẽ xảy ra khi Ngăn xếp cuộc gọi đạt đến kích thước tối đa? Chúng tôi gọi tình huống này là Blowing The Stack .
Thổi đống
Điều này xảy ra khi nhiều giao dịch được yêu cầu hơn khả năng xử lý của Ngăn xếp cuộc gọi. Rất dễ gặp phải trường hợp này, đặc biệt nếu bạn đang sử dụng các cấu trúc sẽ lặp lại mã của chúng ta liên tục.
Hãy xem xét tình huống này với một ví dụ;
function foo() {
foo();
}
foo();

Nhưng sau một thời điểm, số lượng chức năng trong Ngăn xếp cuộc gọi vượt quá kích thước của Ngăn xếp cuộc gọi và trình duyệt sẽ thông báo lỗi như sau;

Chạy mã trong cấu trúc một luồng có thể dễ dàng hơn theo nhiều cách, nhưng nó khá hạn chế.
Trong bài viết này, tôi đã nói về các thành phần cốt lõi của JS Engine. Để hiểu lập trình không đồng bộ, cần phải hiểu các thành phần của Javascript Engine.
tài nguyên
Valentino Gagliardi-Công cụ JavaScript
www.developer.mozilla.org
Lưu ý: Tôi đã chuẩn bị các hình ảnh trong figma.