Analysis of the front interview questions and ideas of “today’s headlines”

Time:2019-12-30

An article and an interview question

Recently, an article called “8 charts to help you see the execution sequence of async / await and promise step by step” attracted my attention.

The author uses a front-end interview topic of “today’s headlines” in 2017 as an introduction to explain the implementation reasons of the final results step by step. It involves many concepts, such as asynchronous execution sequence, macro task, micro task, etc. at the same time, the author limits the scope of execution, which is subject to the browser’s event loop mechanism. Here is the code of the original question:

async function async1 () {
    console.log('async1 start');
    await async2();
    console.log('async1 end');
}

async function async2 () {
    console.log('async2');
}

console.log('script start');

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

async1();

new Promise(function (resolve) {
    console.log('promise1');
    resolve();
}).then(function () {
    console.log('promise2');
});

console.log('script end');

Next, the author gives the answer. We hope that readers can test themselves first.

script start
async1 start
async2
promise1
script end
promise2
async1 end
setTimeout

When I read this question, I first wrote out the result according to my own understanding.

script start
async1 start
async2
promise1
script end
async1 end
promise2
setTimeout

Some important concepts

We need to briefly talk about the concept of event loop.

  • JavaScript is single threaded, and all synchronization tasks are executed in the main thread.
  • In addition to the main thread, there is a task queue. Whenever an asynchronous task has a result, an event is put into the task queue.
  • When all tasks in the main thread are completed, the system will read the events in the task queue “in turn”. The corresponding asynchronous task enters the main thread and starts execution.
  • There will be differences between asynchronous tasks, so the priority of their execution will also be different. It can be roughly divided into micro tasks (such as promise, mutaionobserver, etc.) and macro tasks (such as setTimeout, setinterval, I / O, etc.). In the same event loop, the micro task is always executed before the macro task.
  • The main thread will continue to repeat the above steps until all tasks are completed.

In addition, there is the concept of async / await.

  • Async function can be understood as the syntax sugar of generator function.
  • It is built on promise and is always used with await.
  • Await returns a promise object, or the value of an expression.
  • The goal is to make asynchronous operations more elegant and write like synchronization.

My understanding

And my understanding of the problem.

  • First, in terms of the number of consoles, eight lines of results are output.
  • Take a second glance at the code, see setTimeout, and silently fill it in line 8.
  • Near setTimeout, you can see console. Log (‘script start ‘) and async1(), and confirm that they are synchronization tasks, which will be executed in the main thread first. So, properly fill in script start on line 1 and async1 start on line 2.
  • Next, I met await. Literally, let’s wait. You need to wait for the async2() function to return and block the following code. So, line 3 is filled with async2.
  • It’s time to output console. Log (‘async1 end ‘). However, don’t forget that there is a promise below. It should be noted that when a promise is new, the code in its resolve method will execute immediately. If it’s not for async1()’s wait, promise 1 can get ahead. So, now line 4 is populated with promise 1.
  • Next, the synchronization task console. Log (‘script end ‘) is executed. Fill in line 5 with script end.
  • Lines 6 and 7 are left blank. Review the concept of async / await mentioned above, which aims to make asynchronous writing as synchronous as possible. So, I think console. Log (‘async1 end ‘) is a synchronization task. So, line 6 is filled with async1 end.
  • Finally, it makes sense to fill in promise 2 on line 7.

Different from the author’s answer

Looking back at the author’s answers, we found that there was a problem with the order of lines 6 and 7.

After reading the article patiently, I repeatedly read async1 end and promise 2 for several times, but I still can’t understand why in Chrome browser, promise 2 will output before async1 end.

Then, when I saw the comment area, I found that some people raised the same doubts. @Rhinel proposes that in his 72.0.3622.0 (official version) dev (64 bit) chrome, the result of running out is that async1 end is before promise 2.

Then I thought of the possibility that the specification of JS might change in the future. So I tried it with my react project (Babel loader version in the project is 7.1.5). . babelrc’s presets set stage-3), and the results are consistent with my understanding. In the current version of chrome v71, there is a problem with the execution order here.

Therefore, I also left a comment and discussion for the author in the comment area. @In the end, rhinel also confirmed that in fact, it has only recently released and passed the improvement scheme of this order. This “fast async functions and promises” explains the improvement in detail and its implementation effect. Soon after, the author also added the results of our discussion at the end of his article for readers’ reference.

summary

Finally, I would like to say that although this article is only extended from an interview question, the process of thinking, discussing and verifying the browser execution order. But it is because of these processes that more ideas can collide, concepts can be further understood and norms can be understood.

If there is a chance, I hope to have more in-depth exchanges with you.

To update

To be reasonable, async / await has been out for a long time, but in recent interviews, when asked about asynchronous operation, the interviewer’s answer is promise, and even knows that async / await is rare, it seems that it needs to be further popularized. This is not to say that promise is not good. I just think async / await is good to use. I hope more people can use it. Only when it is used can we further understand it and generate more thinking.

So these two days, I have turned over what I wrote about async function and its advantages over promise. Please go to “the advantages of async / await compared with promise” for the original.

I hope it will help you and look forward to further communication. Thank you!

PS: welcome to my public account “super brother front-end stack” to exchange more ideas and technologies.

Analysis of the front interview questions and ideas of