Use a few interview questions to look at the JavaScript execution mechanism

Use a few interview questions to look at the JavaScript execution mechanism

Previous words

According to JavaScript's operating environment, it is locked as a single thread, and tasks need to be queued for execution. If the website resources are large, this will cause the browser to load very slowly, but in fact it does not. Everyone must have immediately thought of synchronization and asynchrony.

The so-called synchronization and asynchrony are also queuing, but the places of queuing are different.

Synchronous and asynchronous

Synchronous tasks are queued in the main thread, and asynchronous tasks are queued in the event queue.

Synchronous tasks and asynchronous tasks enter different queues, which is what we said above about queuing in different places.

Synchronous tasks enter the main thread, asynchronous tasks enter the event queue, and after the main thread task is executed, the tasks waiting to be executed in the event queue enter the main thread for execution until all tasks in the event queue are executed.

Appetizers

console.log('a')

setTimeout(function(){
    console.log('b')
}, 200)

setTimeout(function(){
    console.log('c')
}, 0)

console.log('d')

adcb

From top to bottom, those that should enter the main thread enter the main thread, and those that should enter the event queue enter the event queue.

Then there are console.log('a') and console.log('d') in the main thread, and the timer setTimeout delays execution for a period of time. As the name suggests, the asynchronous task enters the event queue, waits for the main thread task to be executed, and then enters the main thread for execution.

A timer with a delay of 0 does not mean that it will be executed immediately, but it just means that it will enter the main thread and execute earlier than other timers.

Add a plate

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i)
    }, 1000)
}

Result: Ten 10

Every time the for loop encounters setTimeout, it is put into the event queue and waits for execution until all loops are completed. i is a global variable. When the loop ends, i = 10. When setTimeout is executed again, the value of i is already 10, and the result is ten 10s.

Change var to let. The variable scope is different. Let acts in the current loop, so the i of the timer entering the event queue is different each time, and the final print result will be 0 1 2...9.

Macrotasks Microtasks

In addition to the commonly mentioned synchronous tasks and asynchronous tasks, they can be divided into macro tasks and micro tasks.

Main macro task: the entire script scriptsetTimeoutsetTimeout...

Main microtask: promise.then...

Execution process:

1. The entire script starts executing as a macro task

2. When encountering a microtask, push it into the microtask queue, and push the macrotask into the macrotask queue

3. After the macro task is executed, check whether there are executable micro tasks

4. Found executable microtasks and completed all microtasks

5. Start a new macro task and repeat until all tasks are completed

Let's have a Promise

const p = new Promise(resolve => {
    console.log('a')
    resolve()
    console.log('b')
})

p.then(() => {
    console.log('c')
})

console.log('d')

Result: abdc

1. The entire script enters the macro task queue and starts executing

2. Promise is created and executed immediately, printing ab

3. Encounter promise.then and enter the microtask queue

4. When console.log('d') prints d

5. The entire code is executed as a macro task, and there is an executable micro task. The micro task starts to execute and print c.

setTimeout(function(){
    console.log('setTimeout')
}, 0)

const p = new Promise(resolve => {
    console.log('a')
    resolve()
    console.log('b')
})

p.then(() => {
    console.log('c')
})

console.log('d')

Result: abdc setTimeout

1.setTimeout enters the macro task queue

2. Promise is created and executed immediately, printing ab

3. Encounter promise.then and enter the microtask queue

4. When console.log('d') prints d

5. There are executable microtasks, print c

6. After the microtask is executed, the new macrotask starts to execute, setTimeout starts to execute, and setTimeout is printed

setTimeout(function(){
    console.log('setTimeout')
}, 0)

const p = new Promise(resolve => {
    console.log('a')
    resolve()
    console.log('b')
})

p.then(() => {
    console.log('c')
    setTimeout(function(){
        console.log('setTimeout in then')
    }, 0)
})

console.log('d')

Result: setTimeout in abdc setTimeout then

1. Same as above

2. Execute the microtask to print c, and push it into the macrotask queue when encountering setTimeout

3. The timer delay time is the same, and the macro tasks are executed in sequence, and the setTimeout in setTimeoutthen is printed respectively.

Add some timer

console.log('a');

new Promise(resolve => {
    console.log('b')
    resolve()
}).then(() => {
    console.log('c')
    setTimeout(() => {
      console.log('d')
    }, 0)
})

setTimeout(() => {
    console.log('e')
    new Promise(resolve => {
        console.log('f')
        resolve()
    }).then(() => {
        console.log('g')
    })
}, 100)

setTimeout(() => {
    console.log('h')
    new Promise(resolve => {
        resolve()
    }).then(() => {
        console.log('i')
    })
    console.log('j')
}, 0)

Result: abchjidefg

1. Print a

2.promise is executed immediately and prints b

3.promise.then pushes into the microtask queue

4.setTimeout pushes into the macro task queue

5. After the entire code is executed, the microtask starts to execute, print c, and when setTimeout is encountered, it is pushed into the macrotask queue and waits for execution

6. If there is no executable microtask, start executing the macrotask, and the timer queues for execution according to the delay time

7. Print hj, promise.then pushes into the microtask queue

8. Executable microtask, print i, continue to execute macrotask, print d

9. Execute the macro task with a delay of 100, print ef, execute the micro task and print g, and all tasks are completed

Simple test

console.log('start')

a().then(() => {
  console.log('a_then')
})

console.log('end')

function a() {
  console.log('a_function')
  return b().then((res) => {
    console.log('res', res)
    console.log('b_then')
    return Promise.resolve('return value of method a')
  })
}

function b() {
  console.log('b_function')
  return Promise.resolve('return value')
}

Result: start a_function b_function end res return value b_then a_then

Think about this according to the process of the above example to deepen your understanding

Summarize

  • JavaScript is single-threaded, and tasks need to be queued for execution
  • Synchronous tasks enter the main thread queue, and asynchronous tasks enter the event queue and wait to be pushed into the main thread for execution.
  • A row timer with a delay of 0 does not mean that it is executed immediately, but it is executed earlier than other timers.
  • Further understand the js execution mechanism with macrotasks and microtasks
  • The entire code starts executing as a macro task. During the execution, the macro task and micro task enter the corresponding queue
  • After the execution of the entire code is completed, check whether there are tasks waiting to be executed in the microtask queue. If so, execute all microtasks until the tasks in the microtask queue are completed. If not, continue
  • Execute a new macro task. Whenever a micro task is encountered during the execution of a macro task, it will be pushed into the micro task queue for execution.
  • Repeat this process until all tasks are completed.

The above is a look at the details of JavaScript execution mechanism using a few interview questions. For more information about JavaScript execution mechanism, please pay attention to other related articles on 123WORDPRESS.COM!

You may also be interested in:
  • In-depth understanding of JavaScript event execution mechanism
  • Detailed explanation of JavaScript execution mechanism
  • Thoroughly understand the JavaScript execution mechanism
  • A detailed introduction to JavaScript execution mechanism

<<:  MySQL replication advantages and principles explained in detail

>>:  How to generate a free certificate using openssl

Recommend

Vue+Websocket simply implements the chat function

This article shares the specific code of Vue+Webs...

Implementation steps of mysql master-slave replication

Table of contents mysql master-slave replication ...

Summary of MySQL5 green version installation under Windows (recommended)

1 Download MySQL Download address: http://downloa...

Vue+Openlayer uses modify to modify the complete code of the element

Vue+Openlayer uses modify to modify elements. The...

Vue implements the magnifying glass effect of tab switching

This article example shares the specific code of ...

CSS--overflow:hidden in project examples

Here are some examples of how I use this property ...

Web interview Vue custom components and calling methods

Import: Due to project requirements, we will enca...

Detailed explanation of MySQL semi-synchronization

Table of contents Preface MySQL master-slave repl...

How to open port 8080 on Alibaba Cloud ECS server

For security reasons, Alibaba Cloud Server ECS co...

Summary of MySQL log related knowledge

Table of contents SQL execution order bin log Wha...

How to build Apr module for tomcat performance optimization

Preface Tomcat is a widely used Java web containe...

Detailed explanation of html-webpack-plugin usage

Recently, I used html-webapck-plugin plug-in for ...