[interview questions] analysis of classic interview questions in event cycle

Basic concepts

  1. Process is the program that the computer has run. Thread is the smallest unit that the operating system can schedule operations. It is included in the process Every Tab page in the browser opens a process, which contains many threads
  2. As we all know, JS is a single threaded language. If we encounter very time-consuming operations, the execution of JS will be blocked, which is certainly not what we want to see. Therefore, these time-consuming operations are often not executed by JS threads, but by other threads in the browser. After success, we only need to carry out a callback function at a specific time
  3. Therefore, the concept of event loop is introduced. In event loop, there are two tasks: macro task and micro task
    1. Macro tasks include ajax, setTimeout, setInterval, DOM listening and UI Rendering
    2. Micro tasks include Promise's then callback, Mutation Observer API, queueMicrotask(), etc
  4. Next, let's practice the interview questions directly

Interview question 1

setTimeout(function () {
    console.log("setTimeout1");

    new Promise(function (resolve) {
        resolve();
    }).then(function () {
        new Promise(function (resolve) {
            resolve();
        }).then(function () {
            console.log("then4");
        });
        console.log("then2");
    });
});

new Promise(function (resolve) {
    console.log("promise1");
    resolve();
}).then(function () {
    console.log("then1");
});

setTimeout(function () {
    console.log("setTimeout2");
});

console.log(2);

queueMicrotask(() => {
    console.log("queueMicrotask1")
});

new Promise(function (resolve) {
    resolve();
}).then(function () {
    console.log("then3");
});
  1. Solve the synchronization task first
    1. Output promise1 2
  2. Start solving micro tasks in asynchronous tasks
    1. Output then1 queueMicrotask1 then3
  3. Start resolving macro tasks in asynchronous tasks
    1. Output setTimeout1. In the first timer, the micro task is encountered again, and then the micro task is executed
      1. Output then2 and then then4
    2. Look out of the first timer and see that the second timer starts to output setTimeout2
  4. The final complete output is promise1 2 then1 queueMicrotask1 then3 setTimeout1 then2 then4 setTimeout2

Interview question 2

async function async1() {
  console.log('async1 start')
  // The return result of await asynchronous function and the result of resolve will be used as the resolve result of promise - > synchronization code of the whole asynchronous function
  // The execution code after await will become Execution function after then - > micro task
  // That is to say, console The section log ('async1 end ') is equivalent to that in the then method and will be added to the micro task
  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')
  1. Execute synchronization code first
    1. Output script start async1 start async2 promise1 script end
  2. Start micro task
    1. Output async1 end promise2
  3. Finally, execute the macro task
    1. Output setTimeout
  4. Full output: script start async1 start async2 promise1 script end async1 end promise2 setTimeout

Interview question 3

Promise.resolve().then(() => {
  console.log(0);
  //1. Directly return to 4 micro tasks without any delay 
  // return 4
  //2. Directly return promise Resolve (4) micro task postponed twice
  // return Promise.resolve(4);
  //3. Return thenable object
  return {
    then: ((resolve, reject) => {
      resolve(4);
    })
  }
}).then((res) => {
  console.log(res)
})

Promise.resolve().then(() => {
  console.log(1);
}).then(() => {
  console.log(2);
}).then(() => {
  console.log(3);
}).then(() => {
  console.log(5);
}).then(() => {
  console.log(6);
})

This interview question is somewhat special. You need to remember two conclusions

  1. If the thenable object is returned, the micro task will be postponed once. The thenable object implements promise The function of then can be seen in the code
  2. If Promise Resolve (4), then the micro task will be delayed twice, which is equivalent to using resolve after returning a Promise. The two are equivalent
  3. In order to cooperate with your understanding, I have drawn some pictures for you to see


Interview question 4

This question is a node based event loop, which is different from the browser event loop. You need to remember the following points

The event loop of node is also divided into macro task and micro task

  • Macro tasks: setTimeout, setInterval, IO event, setImmediate, close event
  • Callback of micro task: Promise.promise nextTick,queueMicrotask

Each event loop of node is executed in the following order

  1. next tick microtask queue
  2. other microtask queue
  3. timer queue
  4. poll queue
  5. pcheck queue
  6. close queue
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('setTimeout0')
}, 0)

setTimeout(function () {
  console.log('setTimeout2')
}, 300)

setImmediate(() => console.log('setImmediate'));

process.nextTick(() => console.log('nextTick1'));

async1();

process.nextTick(() => console.log('nextTick2'));

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

console.log('script end')
  1. Perform the synchronization task first
    1. Output script start async1 start async2 promise1 promise2 script end
  2. Then execute the micro task, because node will give priority to the micro task of nextTick
    1. So output nextTick1 nextTick2 first
    2. When outputting other micro tasks, output async1 end promise3
  3. Finally, execute the macro task
    1. Output setTimeout0 setImmediate
    2. Because the timer is delayed for 3ms, other macro tasks will be executed before going back to execute the timer. Therefore, setTimeout2 is output at last
  4. Final output result: script start async1 start async2 promise1 promise2 script end nextTick1 nextTick2 async1 end promise3 setTimeout0 setImmediate setTimeout2

Keywords: Javascript Interview

Added by Tonata on Wed, 09 Mar 2022 08:23:35 +0200