JS is single threaded

The great thing about JavaScript is that it’s single-threaded, meaning you can only do one thing at a time.

Why is JS designed to be a single-threaded language?

As a scripting language, JS is mainly used to complete user interaction and DOM manipulation. If JS has multiple threads at the same time, one thread is modifying the DOM node, and another thread is also modifying the DOM node, then conflicts will occur at this time. The single thread feature avoids the complexity of JS and is also the core feature of JS.

Thread: The smallest unit of CPU scheduling. The unit of a program run based on a thread. A process can have more than one thread. Browsers are multi-processCopy the code

Synchronous and asynchronous

The execution mode of the program is divided into synchronous execution and asynchronous execution.

Synchronous execution

Execute code sequentially, from top to bottom, as follows:

let a = 1
console.log(a)
letLog (b) The output is 1 2Copy the code

Asynchronous execution

It does not wait for the end of the task before starting the next task. For time-consuming operations, the next task is executed immediately after the task is started. The subsequent logic of time-consuming tasks is defined in the form of callback functions, as follows:

The console. The log (" start ")setTimeout(() => {
    console.log('hello') 
}, 100)
console.log('end'The output is start end helloCopy the code

Here setTimeout starts an asynchronous task and executes the setTimeout callback function 100ms after the synchronous code completes.

Implementation process

Single threading means that all tasks need to be queued until the first one finishes before the next one is executed, and if the task takes a long time, the second one has to wait forever. And this line not for large amount of calculation, but because of some IO device slowly) reading data (such as ajax, have to wait until the result come out, down the execution, so js language designers realize that when the main thread can hang wait for the task, first row in the back of the mission, wait for pending tasks have the result, in it, Thus, JS tasks are divided into two types: synchronous tasks and asynchronous tasks.

Task operation mechanism

  • 1. All synchronization tasks are executed on the main thread, forming an execution stack.
  • 2, in addition to the main thread, there is also a “task queue”, as long as the asynchronous task has a result, in the “task queue” to register an event.
  • 3. When all tasks in the execution stack are completed (the execution stack is cleared), the system will read the events in the “task queue”, and the asynchronous tasks corresponding to the events will enter the end waiting state, and then enter the execution stack to start execution.
  • 4. The main thread repeats step 3 repeatedly.

This main thread runs a loop that reads events, also called an event loop.

Browser js code execution process

  • When the js code executes, the memory heap and execution stack are created
  • In order to push the code in the JS script into the execution stack, after the execution of the pop-up
  • When an asynchronous task is encountered, the corresponding webAPI is called and the corresponding thread is started to execute the asynchronous task
  • When the asynchronous task completes, the event is registered in the task queue
  • When the execution stack is empty, the event in the task queue is read, and the callback function is pushed into the execution stack execution, and the execution is read repeatedly until there are no waiting tasks in the task queue.

Macro task micro task

Macro tasks participate in the event loop tasks that need to be queued for execution, such as tasks in a task queue. To create a macro task: I/O, setTimeout, setInterval, setImmediate (Node), requestAnimationFram (browser)

Microtasks do not participate in the event loop, and tasks that can follow macro tasks do not need to be requeued. The operations for creating microtasks are: process.nexttick (node), mutationObserver (browser), Promise.Then catch finally

The macro task is created during the program execution, and the micro task can be created in the macro task or in the micro task. The micro task is registered in the microtask queue separately. After the current macro task is executed, the micro task in the current microtask list will be executed immediately.

Asynchronous solution

// There is currently an Ajax call wrapper methodfunction sendRequest(url, callback) {
      let xhr = new XMLHttpRequest()
      xhr.open('GET', url)
      xhr.onload = callback
 }
Copy the code

The callback function

sendRequest('/api/user', (response) => {// handle response})Copy the code

Problem: Easy to trigger back to hell, making code difficult to maintain, as shown below

sendRequest('/api/user', (response1) => {
    sendRequest('/api/user', (response2) => {
        sendRequest('/api/user', (response3) => {
            //处理response
        })
    })
})
Copy the code

pormise

Handling multiple asynchrony

let p1 = new Promise((resolve, reject) => {
    sendRequest('/api/user', (response) => {
    //resolve or reject
    })
})
let p2 = new Promise((resolve, reject) => {
    sendRequest('/api/user', (response) = > {/ / resolve or reject})}) Promise. All (/ p1, p2). Then (([res1 and res2]) = > {/ / response})Copy the code

Promise’s Then Catch Finally were all microtasks

Promise features
  • Promise has three states: Pending, depressing, and Rejected. The successful and failed states cannot change with each other
  • Promise. then returns a new promise. The subsequent then method registers a callback for the promise returned by the previous THEN method, and the value returned by the previous THEN method is used as an argument to the subsequent then method callback. If a promise is returned in a callback, the callbacks of subsequent THEN methods wait for its result.
  • The second argument to THEN is a callback that catches the promise exception. It cannot catch the error in the first callback function in then. The catch method can catch the promise exception as well as the callback function in THEN.
  • In the then and catch methods of a Promise, the argument is expected to be a function, and value pass-through occurs when the argument passed is not a function, passing the value to the next THEN or catch method

generator

function *gen () {
    let res = yield  sendRequest('/api/user', (response) => response) // handle res}let runGen = gen()
runGen.next()
Copy the code
Generator function features
  • The function name is preceded by an *
  • Generate a controller by calling a function, such as runGen
  • Call the next() method to start executing the function
  • A yield pause was encountered
  • Next () is encountered again and the function continues

async/await

New features in ES7

async callUser() {
    const result = await sendMessage('/api/user', (response) => response)Copy the code
features
  • Async defines an asynchronous function that returns an implicit promise
  • Await must be used in async defined functions
  • The await instruction suspends the execution of the function, waits for the Promise to execute, and then continues to execute the asynchronous function, returning the result
  • Async /await is the syntactic sugar of genterator

—————————————————————— Personal essays —————————————————————