Hướng dẫn line by line execution in javascript - thực thi từng dòng trong javascript
Đầu tiên, bạn đưa ra một giả định không chính xác: JavaScript hiện đại được biên soạn. Các động cơ như V8, Spidermonkey và Nitro Compile JS nguồn vào mã máy gốc của nền tảng máy chủ. Show Ngay cả trong các động cơ cũ hơn, JavaScript không được giải thích. Họ chuyển đổi mã nguồn thành mã byte, mà máy ảo của động cơ thực thi. Đây thực sự là cách mọi thứ trong ngôn ngữ Java và .NET hoạt động: Khi bạn "biên dịch" ứng dụng của mình, bạn thực sự chuyển đổi mã nguồn thành mã byte của nền tảng, mã byte và CIL tương ứng. Sau đó, trong thời gian chạy, một trình biên dịch JIT biên dịch mã byte vào mã máy. Chỉ các động cơ JS rất cũ và đơn giản thực sự diễn giải mã nguồn JavaScript, bởi vì việc giải thích là rất chậm. Vậy tổng hợp JS hoạt động như thế nào? Trong giai đoạn đầu tiên, văn bản nguồn được chuyển thành một cây cú pháp trừu tượng (AST), một cấu trúc dữ liệu đại diện cho mã của bạn theo định dạng mà máy móc có thể xử lý. Về mặt khái niệm, điều này giống như cách văn bản HTML được chuyển đổi thành đại diện DOM của nó, đó là những gì mã của bạn thực sự hoạt động. Để tạo AST, động cơ phải đối phó với đầu vào của các byte thô. Điều này thường được thực hiện bởi một máy phân tích từ vựng. Lexer không thực sự đọc tệp "từng dòng"; Thay vào đó, nó đọc byte-by-byte, sử dụng các quy tắc của cú pháp ngôn ngữ để chuyển đổi văn bản nguồn thành mã thông báo. Lexer sau đó chuyển luồng mã thông báo cho trình phân tích cú pháp, đó là những gì thực sự xây dựng AST. Trình phân tích cú pháp xác minh rằng các mã thông báo tạo thành một chuỗi hợp lệ. Bây giờ bạn có thể thấy rõ lý do tại sao một lỗi cú pháp ngăn mã của bạn hoạt động. Nếu các ký tự bất ngờ xuất hiện trong văn bản nguồn của bạn, động cơ không thể tạo ra AST hoàn chỉnh và nó không thể chuyển sang giai đoạn tiếp theo. Khi động cơ có AST:
Vì vậy, bây giờ bạn có thể thấy rằng tối thiểu, việc thực thi JS xảy ra theo hai giai đoạn. Tuy nhiên, các giai đoạn thực hiện thực sự không có tác động đến lý do tại sao ví dụ của bạn hoạt động. Nó hoạt động vì các quy tắc xác định cách đánh giá và thực thi các chương trình JavaScript. Các quy tắc có thể dễ dàng được viết theo cách mà ví dụ của bạn sẽ không hoạt động, không có tác động đến cách chính động cơ thực sự diễn giải/biên dịch mã nguồn. Cụ thể, JavaScript có một tính năng thường được gọi là nâng cao. Để hiểu được nâng cao, bạn phải hiểu sự khác biệt giữa khai báo hàm và biểu thức chức năng. Đơn giản, một khai báo chức năng là khi bạn khai báo một chức năng mới sẽ được gọi ở nơi khác:
Một biểu thức chức năng là khi bạn sử dụng từ khóa
JavaScript bắt buộc các khai báo chức năng (loại đầu tiên) được gán cho các tên biến ở đầu bối cảnh thực thi, bất kể khai báo ở đâu trong văn bản nguồn (của ngữ cảnh). Bối cảnh thực thi gần như tương đương với phạm vi - theo thuật ngữ đơn giản, mã bên trong một hàm hoặc phần trên cùng của tập lệnh của bạn nếu không bên trong một hàm.regardless of where the declaration appears in source text (of the context). An execution context is roughly equatable to scope – in plain terms, the code inside a function, or the very top of your script if not inside a function. Điều này có thể dẫn đến hành vi rất tò mò:
Bạn mong đợi điều gì sẽ được đăng nhập vào bảng điều khiển? Nếu bạn chỉ cần đọc mã tuyến tính, bạn có thể nghĩ Vì vậy, để kết luận:
Gần đây tôi đã thảo luận với một vài Devs Devs về - cách JS phân bổ bộ nhớ và cách một kịch bản được phân tích cú pháp và thực thi. Đây là một trong nhiều chủ đề quan trọng nhất (hầu hết) không bao giờ là một phần trong sự nghiệp học tập của chúng tôi, không ai cần biết để viết một chương trình JS. Nhưng các chủ đề như thế này là rất quan trọng đối với những nhà phát triển tò mò ngoài kia, những người nghiêm túc với mọi thứ. Tôi đã chọn viết về chủ đề này bởi vì tôi thấy nó khá mơ hồ và mọi người có xu hướng so sánh mọi thứ, đặc biệt là những người quen thuộc với các ngôn ngữ lập trình khác như PHP, C ++, Java, v.v. Một thời gian để tiêu hóa một số khía cạnh quan trọng của JS ban đầu, như làm thế nào JavaScript bị chủ đề đơn có thể không chặn và đồng thời?HOW JavaScript being single-threaded can be non-blocking and concurrent? Bây giờ trước khi chúng ta bắt đầu lặn sâu, hãy làm rõ khái niệm cơ bản và sự khác biệt giữa động cơ JavaScript và môi trường thời gian chạy JavaScript. - Mặt khác, môi trường thời gian chạy JavaScript, vì tên này có trách nhiệm tạo ra một hệ sinh thái với các cơ sở, dịch vụ và hỗ trợ (như mảng, chức năng, thư viện lõi, v.v.) được yêu cầu cho các hướng dẫn thực thi để chạy thành công . Mô hình chức năngHầu như tất cả các trình duyệt web đều có một công cụ JavaScript. Những cái phổ biến nhất là V8 trong Google Chrome và Node.js, Spider Monkey of Mozilla, IE, Chakra, v.v. Mặc dù tất cả các nhà cung cấp trình duyệt này đã triển khai JS khác nhau, nhưng dưới mui xe, tất cả đều theo cùng một mô hình cũ. Hình: 1Gọi ngăn xếp, API web, vòng lặp sự kiện, hàng đợi nhiệm vụ, hàng đợi kết xuất, v.v ... Tất cả chúng ta đều nghe thấy các thuật ngữ buzz này trong công việc hàng ngày của chúng ta. Nói chung, tất cả đều làm việc cùng nhau để giải thích và thực hiện các khối mã đồng bộ và không đồng bộ mà chúng ta viết mỗi ngày. Chúng ta hãy nhìn sâu vào mô hình và cố gắng hiểu những gì họ làm và quan trọng nhất là cách thức. Nhiệm vụ đồng bộCó nghĩa là gì? Giả sử chúng tôi có 2 dòng mã dòng 1 theo sau là Line-2. Đồng bộ có nghĩa là Line-2 không thể bắt đầu chạy cho đến khi Line-1 thực hiện xong.Say we have 2 lines of codes Line-1 followed by Line-2. Synchronous means Line-2 can not start running until the Line-1 has finished executing. JavaScript là một luồng đơn, có nghĩa là chỉ có một câu lệnh được thực thi tại một thời điểm. Khi JS Engine xử lý từng dòng tập lệnh của chúng tôi, nó sử dụng ngăn xếp gọi đơn này để theo dõi các mã được cho là chạy theo thứ tự tương ứng của chúng. Giống như những gì một ngăn xếp làm, một cấu trúc dữ liệu ghi lại các dòng hướng dẫn thực thi và thực hiện chúng theo cách LIFO. Vì vậy, hãy nói rằng nếu động cơ bước vào Bài tập 1: Vì vậy, từ sơ đồ trên cho thấy cách thực hiện theo dòng điển hình xảy ra. Khi tập lệnh của ba câu lệnh console.log () được ném vào JS - Bước 1: 0is pushed into the call stack and executed, once done with execution, it is then popped out of the stack. Now the stack is empty and ready for any next
instruction to be executed.Step 2: 1is pushed and the same thing repeats until - Step 3: is executed and there is nothing left to push and execute.Hãy tham gia vào bài tập tiếp theo của chúng tôi: Bài tập 2: Vậy những gì đang xảy ra ở đây như sau: So what's happening here is as follows: Bước 1: Stack cuộc gọi được thúc đẩy với câu lệnh thực thi đầu tiên của tập lệnh của chúng tôi, cuộc gọi chức năng 2 function call. While executing through the scope of the function 2 our engine encounters another function call 4Bước 2: Do đó, chức năng gọi 4 is pushed into the call stack and the engine starts executing 4function’s body (Note: The function 2is still not finished), again, there’s another function call
8 inside 9 body.Bước 3: Tương tự như vậy, chức năng gọi 8 is pushed into the call stack and the engine starts processing 8 function definition. While the functions 4 and 2still living in the stack waiting for their turn (successor to finish their execution) respectively.Bước 4: Vì vậy, khi động cơ gặp phải câu lệnh 4 statement within the function definition of 8 , well that’s the end
of 8 . Hence 8 is popped out of the call stack as it has finished execution. At this point, the engine is back at executing 4 ‘s offerings.Bước 5: Cũng như động cơ gặp phải câu lệnh 4 statement, the function 4 is popped out and the engine starts executing 2 . Now there’s no return statement within the 2 ‘s scope so the engine executes its body until the end of scope and pops 2 out of the stack at Step
6.Đó là cách mà một kịch bản của các tác vụ đồng bộ được xử lý bởi trình duyệt của chúng tôi mà không liên quan đến bất cứ điều gì khác ngoài ngăn xếp cuộc gọi huyền thoại của Hồi giáo. Nhưng mọi thứ trở nên phức tạp một chút khi động cơ JS gặp một nhiệm vụ không đồng bộ. Nhiệm vụ không đồng bộCó nghĩa là gì có nghĩa là gì? Không giống như đồng bộ, không đồng bộ là một hành vi. Giả sử nếu chúng ta có hai dòng mã dòng 1 theo sau là Line-2. Line-1 là một hướng dẫn tốn thời gian. Vì vậy, Line-1 bắt đầu thực hiện hướng dẫn của nó trong nền (như quy trình daemon), cho phép Line-2 bắt đầu thực thi mà không phải chờ Line-1 kết thúc.Unlike synchronous, asynchronous is a behavior. Say if we have two lines of code Line-1 followed by Line-2. Line-1 is a time-consuming instruction. So Line-1 starts executing its instruction in the background (like a daemon process), allowing Line-2 to start executing without having to wait for Line-1 to finish. Chúng ta cần hành vi này khi mọi thứ chậm. Thực thi đồng bộ mã có vẻ đơn giản nhưng có thể chậm. Các nhiệm vụ như xử lý hình ảnh có thể chậm, các hoạt động tệp có thể thực sự chậm, việc yêu cầu mạng và chờ phản hồi chắc chắn là chậm, tạo ra các tính toán lớn như hơn 100 triệu lần lặp lại cho vòng lặp có phần chậm. Vì vậy, những điều chậm chạp như vậy trong Stack Stack dẫn đến việc chặn chặn. Khi ngăn xếp cuộc gọi bị chặn, trình duyệt sẽ ngăn người dùng ngắt và các câu lệnh mã khác thực thi cho đến khi câu lệnh chặn được thực thi và ngăn xếp cuộc gọi được giải phóng. Do đó, các cuộc gọi lại không đồng bộ được sử dụng để xử lý các tình huống như vậy.slow. Tasks like image processing can be slow, file operations can be really slow, making a network request and waiting for response is definitely slow, making huge calculations like over a 100 million for-loop iteration is somewhat slow. So such slow things in Call stack results in “Blocking”. When the call stack is blocked, the browser prevents the user’s interrupts and other code statements from executing until the blocking statement is executed and the call stack is freed. Hence Asynchronous callbacks are used to handle such situations. Ví dụ: Vâng, hàm Bài tập 3: Nếu chúng ta theo dõi ngăn xếp cuộc gọi, chúng ta có thể thấy: Ở bước 1: Như thường lệ
Bây giờ chúng ta còn lại ba câu hỏi quan trọng: Câu 1. Điều gì đã xảy ra với ____34? Câu hỏi 2. Nó đã trở lại từ đâu? Và câu hỏi 3. Nó đã xảy ra như thế nào? Vì vậy, đây là nơi vòng lặp sự kiện, hàng đợi gọi lại và API Web (trong trình duyệt) bắt đầu. Hãy giới thiệu từng phần trên và trả lời 3 câu hỏi trên thông qua sơ đồ tiếp theo của chúng tôi.Event Loop, Callback Queue, and Web APIs (in browser) kicks in. Let's introduce each of the above pieces and answer the above 3 questions through our next diagram. Hình: 3.2 Trình diễn cuối cùng của toàn bộ mô hìnhBài tập 4: Hãy nhảy ngay vào Let's jump right into Bước 2: Tại thời điểm này Bước 3: Vì vậy, API Web Trình duyệt chịu trách nhiệm của Bước 4: Dòng tiếp theo trong tập lệnh của chúng tôi Bước 5: Bây giờ chúng tôi có một Bước 6: Vòng lặp sự kiện-Nó chịu trách nhiệm lấy phần tử đầu tiên từ hàng đợi gọi lại/nhiệm vụ và đẩy nó vào ngăn xếp cuộc gọi chỉ khi ngăn xếp hoặc miễn phí, vì vậy tại thời điểm này của phương trình của chúng tôi, ngăn xếp cuộc gọi trống rỗng. Event Loop — it is responsible for taking out the first element from the Callback/Task Queue and PUSH it into the Call-Stack only when the stack is empty or free, so at this point of our equation, the Call-Stack is empty. Bước 7: Vì vậy, Bước 8: Vì vậy, một tuyên bố thực thi khác Bước 9: Sau khi Chà, đây là một cuộc biểu tình rất dễ dàng, nhưng mọi thứ trở nên lộn xộn và phức tạp trong các tình huống như khi có nhiều lần được xếp hàng - kết quả khác nhau so với những gì mà thường được mong đợi (đây là một chủ đề thú vị khác để thảo luận). Tôi không biết làm thế nào chính xác tôi có thể chứng minh chủ đề này nhưng có rất nhiều thứ có thể được xây dựng hoặc giải thích tốt hơn, nhưng tôi đã vội vàng và nó đã quá dài. Hy vọng nó sẽ giúp ai đó. Thực thi trong JavaScript là gì?Bối cảnh thực thi chứa mã hiện đang chạy và mọi thứ hỗ trợ thực thi. Trong thời gian chạy ngữ cảnh thực thi, mã cụ thể được phân tích cú pháp, các biến và hàm được lưu trữ trong bộ nhớ, mã byte có thể thực thi được tạo và mã được thực thi.. During the Execution Context run-time, the specific code gets parsed by a parser, the variables and functions are stored in memory, executable byte-code gets generated, and the code gets executed.
JavaScript có được thực hiện tuần tự không?39.1.2 JavaScript thực thi các nhiệm vụ theo tuần tự trong một quy trình.Vòng lặp này còn được gọi là vòng lặp sự kiện vì các sự kiện, chẳng hạn như nhấp chuột, thêm các tác vụ vào hàng đợi.JavaScript executes tasks sequentially in a single process. This loop is also called the event loop because events, such as clicking a mouse, add tasks to the queue.
JavaScript là đồng bộ hay không đồng bộ?JavaScript là một ngôn ngữ lập trình đồng thời, không chặn, không đồng bộ, không đồng thời với rất nhiều sự linh hoạt.asynchronous, concurrent programming language with lots of flexibility.
Làm thế nào để JavaScript được thực thi?Mã nguồn được chuyển qua một chương trình gọi là trình biên dịch, chuyển nó thành mã byte mà máy hiểu và có thể thực thi.Ngược lại, JavaScript không có bước tổng hợp.Thay vào đó, một trình thông dịch trong trình duyệt đọc qua mã JavaScript, diễn giải từng dòng và chạy nó.an interpreter in the browser reads over the JavaScript code, interprets each line, and runs it. |