Browser event loop mechanism maps + examples take you seconds to understand

Original Address

github for more front-end resources

https://github.com/ChenMingK/WebKnowledges-Notes

Three Questions soul

Why JavaScript is single-threaded? Asynchronous JavaScript Why do I need? JavaScript is how to achieve single-threaded asynchronous?

1.JavaScript Why is single-threaded?

There are two threads process1 process2, assuming that JavaScript is multi-threaded, so they can operate simultaneously on the same dom. process1 delete the dom, but process2 edited the dom, simultaneously issued two contradictory orders, the browser exactly how to enforce it? Think so, JavaScript Why is designed to be single-threaded, it is easy to understand it.

2.JavaScript Why asynchronous?

If Asynchronous JavaScript does not exist, the only top-down execution, if the line is very long time to resolve, then the following code will be blocked. For users, it means blocking "stuck", thus leading to a poor user experience, there asynchronous execution JavaScript.

3.JavaScript single-threaded asynchronous is how to achieve it?

Through the event loop to achieve

To take advantage of the computing power of multi-core CPU, HTML5 Web Worker proposed standard that allows JavaScript scripts to create multiple threads, but the main thread child thread completely under control, and shall not operate DOM. So, the new standard does not change the nature of single-threaded JavaScript.

Why JavaScript is a "non-blocking" language? Non-blocking namely: "the program will not stop a task."

console.log("程序时间:" + new Date().getTime())

setTimeout(function () {
     console.log("暂停一秒:" + new Date().getTime())
}, 1000)

console.log('这是暂停一秒之后的时间:' + new Date().getTime())

To simple, if the figure of setTimeout into the C ++ sleep (1000) and the like, then C ++ will indeed be "sleeping" Then some time, and JS will not. If I want to achieve this function? Can be achieved using the Promise:

async function test () {
  console.log('start')
  await sleep(3000)
  console.log('3s has passed')
}

function sleep (ms) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve()
    }, ms)
  })
}

Task Queue

After experiencing an asynchronous event, JavaScript engine will not return results have been waiting for an asynchronous event, but this event will be hung in the execution stack different queues, which we call the task queue.
These tasks are subdivided into macro and micro-task mission

  • Macro task (macrotask): script (global task), the setTimeout, setInterval, setImmediate (node.js unique) , the I / O (read and write disk or network communication), UI rendering (UI interaction events)
  • Micro-task (Microtask): process.nextTick (node.js unique) , Promise.then, Object.observer (obsolete), MutationObserver

Event loop (event loop)

Here we must first be clear: the browser is a process that has multiple threads (see Broswer specific chapter)
In general, the browser has the following five threads:

  • GUI rendering thread
  • JavaScript engine thread
  • Browser event triggers thread
  • Timer trigger thread
  • Asynchronous HTTP request thread

GUI rendering and JavaScript engine thread is the thread mutually exclusive, are among the other threads can be executed in parallel with each other.
Browser, JavaScript engine cycle read from the task queue tasks and perform this operation mechanism is called event loop.

Here Insert Picture Description

More precisely, the event loop is executed according to the following steps:

  1. Perform synchronization code, which belongs to the macro task (at the time of initial synchronization code is the code the whole script)
  2. The execution stack is empty, the query whether there are micro-task (microtask) needs to be performed
  3. Micro performs all tasks
  4. Necessary to render UI
  5. Then start the next round Event loop, execution of the macro task asynchronous code

example

setTimeout(function () {
  console.log(1)
}, 0)

Promise.resolve(function () {
  console.log(2)
})

new Promise(function (resolve) {
  console.log(3)
})

console.log(4)

// 上述代码的输出结果是什么???

The correct answer is ------------------->341
interpreted as follows:

// 遇到 setTimeout 将 setTimeout 回调放入宏任务队列中
setTimeout(function () {
  console.log(1)
}, 0)

// 遇到了 promise,但是并没有 then 方法回调 
// 所以这句代码会在执行过程中进入我们当前的执行上下文 紧接着就出栈了
Promise.resolve(function () {
  console.log(2)
})

// 遇到了一个 new Promise,Promise 有一个原则就是在初始化 Promise 的时候Promise 内部的构造器函数会立即执行,
// 因此在这里会立即输出一个 3,所以这个 3 是第一个输出的
new Promise(function (resolve) {
  console.log(3)
})
// 然后第二个输出 4  当代码执行完毕后回去微任务队列查找有没有任务,
// 发现微任务队列是空的,那么就去宏仁务队列中查找,发现有一个我们刚刚放进去的setTimeout 回调函数,
// 那么就取出这个任务进行执行,所以紧接着输出1
console.log(4)

too easy? Take a look at this question:

console.log('begin'); // 1.begin
setTimeout(() => {
    console.log('setTimeout 1'); // 3.setTimeout 1
    Promise.resolve() // Promise.resolve().then :直接把 then 回调放入微任务队列
        .then(() => {
            console.log('promise 1'); // 5.promise 1
            setTimeout(() => {
                console.log('setTimeout2'); // 8. setTimeout2
            });
        })
        .then(() => {
            console.log('promise 2'); // 7. promise 2  注意7比8要快,then 方法返回一个新的 Promise 对象
        });
    new Promise(resolve => {
        console.log('a'); // 4. a
        resolve();
    }).then(() => {
        console.log('b'); // 6. b
    });
}, 0);
console.log('end'); // 2.end

Guess you like

Origin www.cnblogs.com/cmk1018/p/11347556.html