Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to implement JavaScript single thread and async

2025-03-29 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article "JavaScript single thread and asynchronous how to achieve" most people do not understand, so the editor summed up the following content, detailed, clear steps, with a certain reference value, I hope you can get something after reading this article, let's take a look at this "JavaScript single thread and asynchronous how to achieve" article bar.

Processes and threads

1. Process: an execution of a program that occupies a unique memory space-you can view the process through the windows task manager

two。 Thread: an independent execution unit within a process; a complete process of program execution; the basic scheduling unit of CPU

3. The relationship between process and thread:

* there is usually at least one running thread in a process: the main thread-automatically created after the process starts

* you can also run multiple threads in a process at the same time, and we will say that the program is multithreaded.

* data within a process can be directly shared by multiple threads in it

* data between multiple processes cannot be directly shared

4. Is the browser running single-process or multi-process?

* there are plenty of single processes

* firefox

* there are plenty of multiple processes

* chrome

5. How do I see if the browser is running with multiple processes?

* Task Manager = = > process

6. Is the browser running single-threaded or multithreaded?

* all run with multi-thread

Single thread 1. What is single thread

One of the major features of the JavaScript language is single threading, which means that you can only do one thing at a time.

/ / Chestnut console.log (1) console.log (2) console.log (3) / / output order 1232. Why is JavaScript single thread?

First of all, for historical reasons, when creating the language javascript, the multi-process, multi-threaded architecture was not popular and the hardware support was not good.

Secondly, because of the complexity of multithreading, multithreaded operations need to be locked, and the complexity of coding will increase.

Finally, it is related to its use. as a browser scripting language, the main use of JavaScript is to interact with users and operate DOM. If you operate DOM at the same time, it will eventually lead to unpredictable results of DOM rendering without multithreading locking.

In order to take advantage of the computing power of multicore CPU, HTML5 proposes the Web Worker standard, which allows JavaScript scripts to create multiple threads, but child threads are completely controlled by the main thread and cannot operate DOM. Therefore, this new standard does not change the nature of JavaScript single-threading.

Synchronous and Asynchronous 1, synchronous / Asynchronous tasks of JS

Synchronous task: for a task queued on the main thread, the latter task can be executed only after the previous task has been executed.

All synchronization tasks are executed on the main thread, forming an execution execution context stack.

Asynchronous task: a task executed outside the main thread; there is also a "task queue" (task queue) outside the main thread. When the asynchronous task is completed, it will be put into the task queue in the way of callback function to wait. When the main thread is idle, the main thread will go to the event queue and put the waiting callback function into the main thread for execution. The repeated execution of this process forms the event loop mechanism (Event Loop) of js.

/ / Chestnut / / synchronous console.log (1) / / Asynchronous setTimeout (() = > {console.log (2)}, 100) / / synchronous console.log (3) / / output order 1 322, Why does JavaScript need Asynchronous

If a piece of code is executed for too long during the execution of JS code, the subsequent code can not be executed for a long time, resulting in blocking (that is, jam), which will affect the user experience.

3. How to implement asynchronism in JavaScript 1) execution stack and task queue

In fact, as we have already mentioned above, JS implements asynchrony through event loops.

Let's first understand a few concepts:

JS tasks are divided into synchronous tasks (synchronous) and asynchronous tasks (asynchronous).

Synchronization tasks are executed on the JS engine thread (the main thread), forming an execution stack (call stack)

Event-triggered thread manages a task queue (Task Queue)

Asynchronous task trigger condition is reached, and callback events are put into the task queue (Task Queue)

After all the synchronous tasks in the execution stack are executed, when the JS engine thread is idle, the system reads the task queue, adds runnable asynchronous task callback events to the execution stack, and starts execution.

When a JS file is executed for the first time, the js engine parses the code, adds the synchronization code into the execution stack in the order in which it is executed, and then executes from scratch. If you are currently executing a method, js adds the execution environment of the method to the execution stack, and then enters the execution environment to continue executing the code in it. When the code in this execution environment finishes executing and returns the result, js exits the execution environment and destroys the execution environment, returning to the execution environment of the previous method. This process is repeated until all the code in the execution stack is executed.

Chestnut

/ / (1) console.log (1) / / (2) setTimeout (() = > {console.log (2)}, 100) / / (3) console.log (3)

First parse the whole code, add it to the execution stack in order, and execute it from scratch

Execute (1) first, which is synchronous, so print 1 directly

Execute (2) and find that it is setTimeout, so call the browser's method (webApi) to execute, and add console.log (2) to the task queue after 100ms.

Execute (3), synchronous, print 3 directly

The execution stack has been cleared, now check the task queue, (if the execution is too fast, the task queue may still be empty at this time, before 100ms, the print of (2) has not been added to the task queue, so keep checking until there are tasks in the queue), and find that there is console.log (2), so add it to the execution stack, execute console.log (2), synchronize the code, and print 2 directly (if this is an asynchronous task It will also go through the loop again:-- > task queue-> execution stack)

So the result is 1, 3, 2.

Note: setTimeout/Promise et al. We call it a task source. And those who enter the task queue are the callbacks they specify.

2) Macro task (macro task) and micro task (micro task)

The above loop is only a macro statement. In fact, there are differences between asynchronous tasks, which are divided into macro tasks (macro task) and micro tasks (micro task). In the latest standards, they are called task and jobs

What are the macro tasks: script (overall code), setTimeout, setInterval, setImmediate, Imax O, UI rendering (rendering)

What are the micro tasks: process.nextTick, Promise, Object.observe (obsolete), MutationObserver (new html5 feature)

Let's explain the implementation process in more detail:

When the execution stack is executed, the macro task is placed in the task queue of a macro task, and the micro task is placed in the task queue of a micro task. When the current execution stack is empty, the main thread will check whether there are any events in the micro task queue. If the micro-task queue does not exist, a task is removed from the macro task queue and added to the current execution stack; if the micro-task queue exists, all tasks in the micro-task queue are executed in turn until the micro-task queue is empty (again, the events in the queue are added to the execution stack), and then the first event in the macro task queue is added to the current execution stack. Over and over again, enter the cycle.

Note:

There can be multiple task queues for both macro and micro tasks

When the current execution stack is finished, all events in the micro-task queue will be processed immediately, and then an event will be extracted from the macro task queue. In the same event loop, micro tasks are always executed before macro tasks.

Cycle strategies may be different in different operating environments. Chrome and node environments are discussed here.

Chestnut

/ / (1) setTimeout (() = > {console.log (1) / / Macro Task}, 100) / / (2) setTimeout () > {console.log (2) / / Macro Task}, 100) / / (3) new Promise (function (resolve,reject) {/ / (4) console.log (3) / / Direct print resolve (4)}) .then (function (val) {/ / (5) console.log (val)) / / Micro tasks}) / / (6) new Promise (function (resolve,reject) {/ / (7) console.log (5) / / print resolve (6)}) .then (function (val) {/ / (8) console.log (val)) / / Micro tasks}) / / (9) console.log (7) / / Direct print / / (10) setTimeout (() = > {console.log (8) / / Macro tasks, single earlier than (1) (2) Macro tasks}, 50)

The correct printing order of the above code in node and chrome environment is 3 5 7 4 6 8 1 2

Let's analyze the execution process:

All code is added to the execution stack after parsing

Execute (1), macro task, call webapi setTimeout, this method puts the callback function into the task queue of the macro task after 100ms

Execute (2), same as (1), but a little later than (1)

Execute (3), execute new Promise synchronously, then execute (4), print 3 directly, then resolve (4), and then. Then (), put (5) in the task queue of the microtask

Execute (6), as above, print 5 first, then execute resolve (6), and then add the contents (8) of .then () to the task queue of the microtask.

Execute (9), synchronize code, print 7 directly

Execute (10), same as (1) and (2), but for a shorter time, the callback console.log (8) will be added to the task queue of the macro task after 50ms

Now the execution stack is empty, start to check the micro-task queue, find (5), add to the execution stack execution, is the synchronous code, directly print 4

The task queue is finished again, check the micro-task queue, find (8), print 6

The task queue is finished again, check the micro task queue, no tasks, and then check the macro task queue. If you exceed the 50ms, you will find that console.log (8) is in the macro task queue, so print 8 is executed.

Print 1 2 in turn

Note: because rendering is also a macro task, rendering needs to be performed after a stack execution, so if there are several code synchronously changing the same style in the stack at the same time, only the last one will be rendered.

The above is about the content of this article on "how to achieve JavaScript single-threading and asynchronism". I believe we all have a certain understanding. I hope the content shared by the editor will be helpful to you. If you want to know more about the relevant knowledge, please follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report