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

Practical way to build selenium grid distributed environment with docker

Recently, I needed to test the zoom video confere...

How to implement load balancing in MySQL

Preface MySQL is a high-speed, high-performance, ...

How to use macros in JavaScript

In languages, macros are often used to implement ...

js to achieve simple accordion effect

This article shares the specific code of js to ac...

jQuery+Ajax to achieve simple paging effect

This article shares the specific code of jquery+A...

MySQL batch removes spaces in a certain field

Is there any way to remove spaces from a certain ...

Detailed explanation of the process of using docker to build minio and java sdk

Table of contents 1minio is simple 2 Docker build...

MySQL 5.7.17 installation and configuration method graphic tutorial (windows10)

MySQL 5.7.17 installation and configuration metho...

Example operation MySQL short link

How to set up a MySQL short link 1. Check the mys...

MySQL 8.0.20 winx64 installation and configuration method graphic tutorial

This article shares with you the installation and...

Detailed explanation of the relationship between React and Redux

Table of contents 1. The relationship between red...

Example of how to upload a Docker image to a private repository

The image can be easily pushed directly to the Do...

MySQL 8.0.12 installation and configuration method graphic tutorial

Record the installation and configuration method ...

CSS HACK for IE6/IE7/IE8/IE9/FF (summary)

Since I installed the official version of IE8.0, ...

Docker generates images through containers and submits DockerCommit in detail

Table of contents After creating a container loca...