preface
It is well known that JavaScript is single-threaded, but it is inevitable that JavaScript also needs to perform asynchronous tasks, such as the following example
function foo() {
console.log("first");
setTimeout(( function(){
console.log( 'second' );
}),5);
}
for (var i = 0; i < 1000000; i++) {
foo();
}
Copy the code
In the example above, the results of the execution will all print first and then second, instead of alternating. In this process, it is obvious that concurrent asynchronous tasks are happening.
JavaScript
Why single threaded?
As a Java programmer, one of the first reactions to learning that JavaScript is single-threaded is to wonder why a language is designed to be single-threaded. Why can’t it use multithreading for efficiency?
The single thread of JavaScript, relative to its purpose. As a browser scripting language, JavaScript’s primary purpose is to interact with users and manipulate the DOM. This means that it has to be single-threaded, which can cause complex synchronization problems. For example, if there are two threads of JavaScript at the same time, one thread adds content to a DOM node, and the other thread removes that node, which thread should the browser use?
So, to avoid complexity, JavaScript has been single-threaded since its inception, and this has been a core feature of the language and will not change.
JavaScript
How to implement asynchrony?
Now that we know why JavaScript is single-threaded, how can it be asynchronous? JavaScript’s asynchronous capabilities are primarily provided by the runtime environment
JavaScript
The operating environment of
JavaScript Runtime
That isJavaScript
Where the code runs. Such asJavaScript
Can be found inchrome
Can also be executed innode
In the implementation,chrome
withnode
Are allJavaScript Runtime
JavaScript Runtime includes JavaScript Engine and WebAPI. JavaScript Engine converts JavaScript we write into more efficient machine code to achieve better performance. JavaScript in Chrome is handled by the V8 engine. V8 engine mainly consists of two parts: memory heap and execution stack
- Memory heap: Used for allocation
JavaScript
Memory used by the program. - Execution stack: In the execution stack, your
JS
The code is read and executed line by line.
In addition to the engine, JavaScript Runtime also provides WebAPI for JavaScript code to call, WebAPI provides network request, timer, event listener, etc. Because JS Runtime is not single threaded, it holds a thread pool, Therefore, code in WebAPI runs on other threads, which naturally provides asynchronous capability
Event loop mechanism
JS
It is divided into synchronous tasks and asynchronous tasks. Synchronous tasks are executed on the main thread, forming an execution stack- Code calls in the stack
WebAPI
When asynchronous tasks are completed, they add various events to the event queue - When the code on the stack finishes executing, it reads the events in the event queue to execute those callbacks
- The execution stack and the task queue do this, which is the event loop mechanism
It is important to note that once all of the execution stack (JS engine idle) at this time synchronization task has been completed, the system will read the task queue, will be able to run the asynchronous task are added to the executable stack So the setTimeout setting time is not accurate, may push it to the event list, the main thread is not free, are performing other code, So there’s an error.
conclusion
JavaScript is essentially a scripting language that runs in the browser and is designed as a single-threaded language for simplicity and to avoid synchronization problems when manipulating the DOM. The asynchronous capability of JavaScript is provided by the runtime environment. Through WebAPI and event loop mechanism, single-threaded JS can also perform asynchronous tasks.
The resources
JavaScript runtime mechanism details: The Event Loop is a threaded, non-blocking, asynchronous, and concurrent language