I have a very vague impression of JavaScript. It is single-threaded and asynchronous. This article mainly talks about how JavaScript works. But before that, let us first understand these concepts (learn now and sell now).
Process is the unit of system resource allocation and scheduling. A running program corresponds to a process. A process includes running programs and the memory and system resources used by the programs. If it is a single-core CPU, there is only one process running at the same time. However, a single-core CPU can also run multiple tasks at the same time. For example, you can listen to NetEase Cloud Music’s daily recommended songs while writing a blog post on NetEase Youdao Cloud Notes. This counts as two processes (multi-process). The running mechanism is to play songs for a while and respond to your typing for a while. However, because the CPU switching speed is very fast, you can’t feel it at all, so that you think these two processes are running at the same time. Resources are isolated between processes.
What is Thread? A thread is the executor under a process. A process will start at least one thread (the main thread), and it can also start multiple threads. For example, NetEase Cloud Music plays audio and displays lyrics at the same time. The operation of multi-process is actually executed through threads in the process. Threads under a process share resources. When multiple threads operate the same resource at the same time, resource contention occurs. This is another question.
Parallelism refers to the running status of a program, where several things are processed in parallel at the same time. Since one thread can only process one thing at the same time, parallelism requires multiple threads to perform multiple things at the same time.
Concurrency (Concurrency) refers to the design structure of the program so that multiple things can be processed alternately at the same time. The point is, only one thing is executing at a time. For example, a single-core CPU can realize the process of running multiple tasks concurrently.
Synchronization and asynchronous refer to the behavior of the program. Synchronous (Synchronous) means that when the program makes a call, it waits until the result is returned. It will not return until there is no result. In other words, synchronization means that the caller actively waits for the calling process.
Asynchronous (Asynchronous) returns immediately after issuing a call, but the result will not be returned immediately. The caller does not have to wait actively. When the callee gets the result, it will actively notify the caller.
For example, go to a milk tea shop to buy drinks. Synchronization means that a customer states a need (request) and then waits for the waiter to prepare the drink. The customer leaves after getting the drink he ordered; then the next customer continues to repeat the above process. Asynchronous means that customers line up to order first, and after ordering, they hold the order aside. The waiter will call their number when it is ready. When called, you just go and get it.
So threads have no direct relationship with synchronization and asynchrony. Single threads can also achieve asynchronous implementation. As for the implementation method, it will be discussed in detail below.
Blocking and non-blocking refer to the waiting state. Blocking means that the thread is "suspended" while the call is waiting (CPU resources are allocated elsewhere).
Non-blocking (Non-blocking) means that the waiting process CPU resources are still in the thread, and the thread can also do other things.
Take the example of queuing up to buy a drink. Blocking means that you can't do anything while waiting. Non-blocking means that you can do other things first while waiting.
So, synchronization can be blocking or non-blocking, and asynchronous can be blocking or non-blocking.
After roughly understanding the above concepts, you will know that there is no contradiction between single-threading and asynchronous. So how is JS executed? JS is actually a language. Whether it is single-threaded or multi-threaded depends on the specific operating environment. JS is usually executed in the browser, and is parsed and run by the JS engine. Let’s take a closer look at the browser.
The most popular browsers currently are: Chrome, IE, Safari, FireFox, and Opera. The browser's core is multi-threaded. A browser usually consists of the following resident threads:
Rendering engine thread: As the name suggests, this thread is responsible for rendering the page
Usually when talking about browsers, we will talk about two engines: rendering engine and JS engine. The rendering engine is how to render the page. Chrome/Safari/Opera use the Webkit engine, IE uses the Trident engine, and FireFox uses the Gecko engine. Different engines implement the same style inconsistently, which leads to the browser style compatibility issue that is often criticized. We will not discuss it in detail here.
The JS engine can be said to be a JS virtual machine, responsible for the parsing and execution of JS code. It usually includes the following steps:
Lexical analysis: Decompose the source code into meaningful word segments
Grammar analysis: Use a syntax analyzer Parse the word segmentation into a syntax tree
Code generation: Generate code that the machine can run
Code execution
The JS engines of different browsers are also different. Chrome uses V8, FireFox uses SpiderMonkey, Safari uses JavaScriptCore, and IE uses Chakra.
Going back to the statement that JS is single-threaded, essentially, the browser only opens one JS engine thread to parse and execute JS during runtime. So why only one engine? If there are two threads operating the DOM at the same time, will the browser be at a loss again? !
After talking so much, we finally want to talk about the entire running process of JS.
Let’s first look at how the JS synchronization execution process is achieved? This involves a very important concept - execution context. One of my translations, Deep Learning JavaScript Closures, explains this concept in great detail.
The execution context records the environment when the code is running. There is one execution context in effect in the current running state. So what exactly is recorded in the execution context? There are probably lexical environment, variable environment, etc. To give a simple example:
var x = 10; function foo(){ var y=20; function bar(){ var z=15; } bar(); } foo();
When the code is run, it first enters the global context. Then when foo()
is executed, the foo context is entered. Of course, the global context is still there at this time. When bar()
is executed, the bar context is entered again. After execution bar()
, return to the foo context. After executing foo()
, return to the global context. Therefore, the execution context of the execution process will form a call stack (Call stack), first in, last out.
// 进栈 3 bar Context => => 2 foo Context => 2 foo Context 1 global Context 1 global Context 1 global Context // 出栈 3 bar Context 2 foo Context => 2 foo Context => => 1 global Context 1 global Context 1 global Context
During the JS execution process, there is and is only one execution context at work. Because JS is single-threaded, it can only do one thing at a time.
The above processes are all executed synchronously.
Let’s review what native asynchronous events come with JS:
setTimeout
setInterval
Event listening
Ajax request
etc. .
#The asynchronous effect of JS benefits from the execution environment of the browser. In fact, the browser opens another thread to handle these BOM events. Example:
function foo(){ console.log(1); } function bar(){ console.log(2); } foo(); setTimeout(function cb(){ console.log(3); }); bar();
According to the analysis in the previous section, first enter the global context, run to foo()
, and enter the foo context environment; execute console.log(1)
, the console outputs 1; the foo context is popped out of the stack, runs to setTimeout
, and is handed over to the browser's timing processing thread; runs to bar()
, enter the bar context; execute console.log(2)
, the console outputs 2; foo context pops; wait until browser thread finishes executingsetTimeout
, return the cb()
callback function to the current task queue; when it is found that the execution stack is empty, the browser's JS engine will execute a loop and The head of the event queue is dequeued to the JS execution stack; execute cb()
to enter the cb context environment; execute console.log(3)
, the console outputs 3; event queue If it is empty, the global context is popped off the stack.
The above is the event loop mechanism of the JS engine, which is a mechanism to achieve asynchronous implementation. It mainly involves browser thread, task queue and JS engine. Therefore, we can see that the asynchronous request of JS relies on the browser of its running environment to process and return the result. Moreover, this also explains why this
of those callback functions points to window
, because these asynchronous codes are executed in the global context.
Afterword: I don’t know if I understood it correctly, and I don’t know if I explained it clearly or clearly. If there is any inappropriateness, please point it out.
Reference materials:
JavaScript: Thoroughly understand synchronization, asynchronous and event loop (Event Loop)
Still confused Concurrency and parallelism?
IMWeb Community Browser process? Thread? stupidly can not tell!
In-depth analysis of Javascript being single-threaded
A brief introduction to JavaScript single-threading and browser event loop
AlloyTeam [Turn to Javascript series] Talking about event loop model from setTimeout
Mustache Brother JavaScript asynchronous programming principle
Ruan Yifeng JavaScript running Detailed explanation of the mechanism: Let’s talk about Event Loop again
[Pu Ling’s Commentary] Detailed explanation of JavaScript running mechanism: Let’s talk about Event Loop again
Philip Roberts: Help, I'm stuck in an event-loop.
The above is the detailed content of Detailed explanation of JavaScript operating mechanism and conceptual analysis. For more information, please follow other related articles on the PHP Chinese website!