preface

Recently, I saw a very classic interview question, which was very interesting:

setTimeout(() => { console.log(1); }, 0); new Promise((resolve) => { console.log(2); resolve(); }).then(() => { console.log(3); }); console.log(4); // Output the final resultCopy the code

I wrote down 2, 4, 1, 3. Finally, the interviewer told me that this was the wrong answer and the correct answer was 2, 4, 3, 1. However, the interviewer was not very professional and only knew the answer but not the principle, so he decided to study it at home.

Browser environment

Single threaded versus asynchronous

As we all know, JavaScript is a single-threaded execution language that processes tasks one by one.

console.log(1); console.log(2); console.log(3); // Result 123 is displayedCopy the code

But ajax, setTimeout, and the like are not blocking the process:

console.log(1); setTimeout(() => { console.log(2); }, 0); console.log(3); SetTimeout does not block subsequent processesCopy the code

In fact, JavaScript single thread means that the browser only has one thread when interpreting and executing JavaScript code, namely the JS engine thread. The browser itself also provides other threads to support these asynchronous methods.

  • JS engine thread
  • Event trigger thread
  • Timing trigger thread
  • Asynchronous HTTP request threads
  • GUI rendering thread
  • .

Browser event mechanism

The browser maintains an execution stack as it executes js code, and each method is executed on the stack and then out of the stack (FIFO). At the same time, the browser also maintains a message queue, all asynchronous methods, after the completion of execution will be callback method into the message queue, when all tasks in the execution stack are completed, the browser starts to look for tasks in the message queue, the first task into the message queue to execute.

For example, the previous code execution steps:

console.log(1);
setTimeout(() => {
    console.log(2);
}, 0);
console.log(3);
Copy the code
  • 1. Add console.log(1) to the stack and run it.
  • 2. Assign setTimeout to the browser asynchronous process.
  • 3. Console. log(3) is thrown to the execution stack, executed, and removed from the stack after execution.
  • 4. When setTimeout expires, throw the callback to the message queue.
  • 5. The execution stack is empty. The task is fetched from the message queue and executed in console.log(2).

Macro and micro tasks

So if two different types of asynchronous tasks are executed, which one will be executed first? As mentioned in the interview question, which will be executed first, setTimeout or promise? This is where concepts come in: macro tasks and micro tasks. The concept is as follows:

  • Macro tasks: code blocks executed synchronously by JS, setTimeout, setInterval, XMLHttprequest, etc.
  • Microtasks: Promise, process.nextTick (node environment), etc.

The tasks executed in the execution stack are all macro tasks. When the macro task meets a Promise, it will create a micro-task, and when the Promise state is fullfill, it will be inserted into the micro-task queue. After a macro task is completed, the microtask queue is checked to see if there are any tasks that need to be executed. If there are any tasks in the microtask queue, all tasks in the microtask queue are executed in sequence. Then start the next macro task. Specific steps:

  1. Execute the main code block
  2. If you encounter a Promise, put anything after then into a microtask queue
  3. After a macro task is executed, check whether there are tasks in the microtask queue
  4. Perform all microtasks, if any
  5. After the execution, start the next macro task.
setTimeout(() => {
    console.log(1);
}, 0);

new Promise((resolve) => {
    console.log(2);
    resolve();
}).then(() => {
    console.log(3);
});

console.log(4);
Copy the code

The steps to this interview question:

  1. SetTimeout Throws the browser to the asynchronous thread for processing, since the time is 0, immediately into the message queue
  2. Console. log(2) in new Promise is added to the stack, executed, and exited
  3. Add the content immediately after resolve, then to the microtask queue
  4. Console. log(4) is added to the stack and exited after execution
  5. Check the microtask queue and execute console.log(3).
  6. The next macro task is console.log(1).

The node environment

The event mechanism in a Node environment is much more complex than in a browser, and node’s event polling has a concept of phases. Perform all microtasks such as process.nexttick at each phase switch.

The timer period

Execute all timed events whose time has expired

Peding callbacks phase

This phase performs any I/O callback that was not performed in the previous poll phase, usually reporting an error.

idle.prepare

You can ignore

Poll phase

This stage is particularly complicated

  1. Block until all I/O operations are performed and all callbacks are executed.
  2. After all I/O callbacks are executed, check whether there is a timer. If so, return to the timer phase
  3. If there is no timer, enter the check phase.

The check phase

Perform setImmediate

The close callbacks phase

Execute all close callback events, such as socket disconnection.

Help wanted!!

Bytedance interactive Entertainment infrastructure team is hiring! There are posts in Beijing, Shenzhen and Hangzhou!

Who we are

Byte established the earliest front-end architecture team, which is now the largest and most professional. There are hundreds of front-end business team directly in hand, and the product DAU reaches 100 million level. There is no quarrel with PM and UI every day, and there is a good technical atmosphere.

Work at ordinary times

Responsible for front-end architecture design, implementation and optimization of large-scale complex business scenarios such as Douyin, Douyin Volcano edition and Live Broadcasting

  1. Responsible for the architecture of one or several technical scenarios such as PC, H5, Hybrid, App Native, BFF, RPC, etc.
  2. Formulate development specifications, build and optimize engineering system, improve development efficiency, quality and performance, and ensure stable operation of business;
  3. Identify problems with existing processes and structures and continuously improve them;
  4. Solve the technical pain points and difficulties encountered in the business;
  5. Follow up the industry’s cutting-edge technology, to ensure the advancement of team technology.

Job requirements

  1. 1. Bachelor degree or above, major in computer science or related; Good computer skills, familiar with data structure, network, etc.
  2. Have certain ability and experience of architecture and scheme design, have certain ability of scheme communication and promotion;
  3. Have some knowledge of back-end technology, familiar with a back-end language (Java/GO etc.);
  4. Experience in front-end engineering (e.g. webpack, rollup, etc.), Nodejs, rendering framework (e.g. React or Vue, etc.), middle and background building system is preferred.
  5. Experience in large website architecture is preferred; High technical enthusiasm and initiative is preferred.

pluses

  1. Participated in or led excellent open source projects;
  2. Have excellent technical blog, blog.

Interested parties can add my wechat to explain the purpose of the visit: