SoFunction
Updated on 2025-03-01

Single-threaded principle of JS internal event mechanism

Task Queue

Main thread: Executing code will generate a function call stack.

  • macro-task (macro task, new name: task) includes: script (overall code), setTimeout, setInterval, setImmediate, I/O, UI rendering.
  • micro-task (micro-task, new name: jobs) includes: , Promise, (deprecated), MutationObserver (new feature of html5, only one in the queue)

Task classification

Synchronize tasks, statements are executed in order of statements. The previous one has not been executed, and the subsequent statements will not be executed.

Asynchronous tasks, statements are not executed in the order of statements. When the code is executed, they are added to the corresponding task queue and the execution is delayed.

Single threaded

The main thread starts the first loop from script (the overall code). Then the global context enters the function call stack. Until the call stack is cleared (the world is left), then execute all jobs. After all executable jobs are executed. The loop starts from task again, find one of the task queues to execute, and then execute all jobs, so that the loop continues.

Things to note

  • setTimeout The minimum interval cannot be less than 4 milliseconds, otherwise it will increase automatically.
  • The rendering of the DOM is performed every 16 milliseconds because the monitor is 60 Hz and refreshes every 16ms.
  • Tasks maintain a queue in the jobs and are executed before other jobs tasks.
  • The bubbling event will be inserted into the main thread directly after the child element event is executed. If the main thread is not empty, then the jobs execution will be preceded.

Classic Examples

Example details:/2015/tasks-microtasks-queues-and-schedules/

Click via mouse

<div class="outer">
 <div class="inner"></div>
</div>
// Let's get hold of those elements
var outer = ('.outer');
var inner = ('.inner');
// Let's listen for attribute changes on the
// outer element
new MutationObserver(function() {
 ('mutate');
}).observe(outer, {
 attributes: true
});
// Here's a click listener…
function onClick() {
 ('click');
 setTimeout(function() {
  ('timeout');
 }, 0);
 ().then(function() {
  ('promise');
 });
 ('data-random', ());
}
// …which we'll attach to both elements
('click', onClick);
('click', onClick);
// Output resultclick
mutate
click
mutate
promise
promise
timeout
timeout

Advanced-execute through js

<div class="outer">
 <div class="inner"></div>
</div>
// Let's get hold of those elements
var outer = ('.outer');
var inner = ('.inner');
// Let's listen for attribute changes on the
// outer element
new MutationObserver(function() {
 ('mutate');
}).observe(outer, {
 attributes: true
});
// Here's a click listener…
function onClick() {
 ('click');
 setTimeout(function() {
  ('timeout');
 }, 0);
 ().then(function() {
  ('promise');
 });
 ('data-random', ());
}
// …which we'll attach to both elements
('click', onClick);
('click', onClick);
();
// Output resultclick
click
mutate
promise
promise
timeout
timeout

Since the click event is executed by js, when the inner onClick function is executed, the scope of the () statement has not yet been backed off the stack, and the main thread call stack is not empty, resulting in the jobs queue task not being executed, and neither the mutate nor the promise statement can be executed in the event loop. This executes the onClick function of outer. After the onClick function of outer is executed, the () statement will be back off the stack and then the jobs task is executed.

There is only one mutate because there can only be one MutationObserver task in the jobs queue. When the second creation is created, the previous MutationObserver task was not executed and it is no longer created.

Summarize

The above is the single threading principle of the internal event mechanism of JS introduced to you by the editor. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. Thank you very much for your support for my website!