Event loops seconds to understand

Event loops seconds to understand

Brief introduction

JS is a single-threaded scripting language, designed to be single-threaded why?

For example, assume that JS is multi-threaded scripting language, A thread modify the DOM, B thread deleted DOM, once completed implementation of the first thread B, DOM is deleted, A thread is being given, in order to avoid problems such as this, is JS designed for single-threaded

Question is a single thread can only do one thing, the second thing to do, and so the first thing to be done in advance. If there is a demand for updated data every five minutes, with setInterval go time, so this page JS never be able to do other things, the thread has been occupied with setInterval. To make JS can perform multiple tasks at the same time, the introduction of Event loops (event loop) mechanism

Event loops are divided into two kinds of queues, task queue, microtask queue, the industry is generally called a macro task queue tasks, microtask translated called micro-tasks.

task queue and queue microtask execution order is what?

When beginning the implementation of the code, the code as a whole is a task, perform the task immediately, in the implementation process

  • Encounter setTimeout, setInterval, I / O, setImmediate (Nodejs environment) go out into the task queue push
  • Encounter Promise.then / catch / finally, MutationObserver, process.nextTick (Nodejs environment) go out into the queue push microtask

After each perform a task, the queue will see microtask there is no task to be performed, and if so, press the FIFO principle followed by the implementation of the task, and then back to the task execution queue finished, remove a task to perform; if no, directly to the next task, and so on, this is the Event loops, similar to a recursive implementation process

Case

According to the above rules, consider the following code output sequence

// 先自己思考一下输出顺序
console.log('script start');

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

Promise.resolve().then(function () {
  console.log('promise');
}).then(function () {
  console.log('then');
});

console.log('script end');

analysis:

  1. Overall the code as the first task, started from top to bottom
  2. Exportscript start
  3. Encounter setTimeout(), push to the task queue, waiting to be executed
  4. Encountered Promisefirst then(), push to microtask queue, waiting to be executed
  5. Exportscript end
  6. The first task execution is complete, view microtask queue, has the task to begin execution
  7. Output promise, a second face then(), queue Push to microtask
  8. Just push the outputthen
  9. microtask queue execution is completed, a task execution removing
  10. Exporttimeout

Output order: script start -> script end -> promise -> then -> timeout

Upgrade, return Promise

The above example Promise upgrade, assuming that there are internal Promise.then Promise, how analysis?

Promise.resolve().then(function () {
  console.log('promise');
  return new Promise((resolve, reject) => {
    console.log('inner promise');
    resolve();
  }).then(() => {
    console.log('inner then1');
  }).then(() => {
    console.log('inner then2');
  })
}).then(function () {
  console.log('then');
});

analysis:

  1. Overall the code for the first task, started from top to bottom
  2. The first encounter then, push queue to microtask
  3. The first task execution is complete, view microtask queue, has the task to begin execution
  4. Export promise
  5. Entering the new Promise, output inner promise
  6. Encountered an internal new Promise first then, push queue to microtask
  7. Just push the output inner then1
  8. Encountered an internal new Promise second then, push queue to microtask
  9. Just push the output inner then2
  10. Internal new Promise executed, then get a first external promise return value, continue down, then its second face, queue Push to microtask
  11. Just push the output then

Output order: promise -> inner promise -> inner then1 -> inner then2 -> then

Note: When then chained calls, if the previous method then return the object to a new Promise, back then waits for the new Promise object state after change, will be implemented, in other words, by the execution of two then becomes asynchronous to synchronize, and if the return get rid of it?

Change, no return Promise

Promise.resolve().then(function () {
  console.log('promise');
  new Promise((resolve, reject) => {
    console.log('inner promise');
    resolve();
  }).then(() => {
    console.log('inner then1');
  }).then(() => {
    console.log('inner then2');
  })
}).then(function () {
  console.log('then');
});

analysis:

  1. Overall the code for the first task, started from top to bottom
  2. The first encounter then, push queue to microtask
  3. The first task execution is complete, view microtask queue, has the task to begin execution
  4. Export promise
  5. Entering the new Promise, output inner promise
  6. Encountered an internal new Promise first then, push to microtask queue, as with the first six steps above
  7. In this case, then a first synchronization code in an external object has been performed over Promise, then performs its second then, queue Push to microtask
  8. Continue microtask, output inner then1
  9. To the interior of the second new Promise then, push the queue microtask
  10. Continue microtask, output then
  11. Final output inner then2

Output order: promise -> inner promise -> inner then1 -> then -> inner then2

Summary: After removing the return, then been performed preceding the synchronization code will then jump to the next

Think

Finally, think about a problem, the following error can be captured to catch it? why?

new Promise(function (resolve, reject) {
  setTimeout(function () { 
    throw new Error('test') 
  }, 0)
  resolve('ok');
}).catch(err => {
  console.error(err);
});

Familiar with the Event loops, it is easy to answer this question: Can not captured. Because of an error in the internal setTimeout throws, setTimeout and .catch not perform the same task, throw the wrong time, catch has been carried over.

I feel good, a star point it Github

Guess you like

Origin www.cnblogs.com/wangmeijian/p/12541633.html