JS feed (Line) process, the micro (macro) task, with the (iso) summarizes the steps

Foreword

“JavaScript 是单线程、异步、非阻塞、解释型脚本语言。”

Browser process

Process : a browser page is a new process, the process is the smallest unit of CPU resource allocation (which system will allocate memory);

  • Browser process (http communication)
  • Third-party plug-in process
  • GPU processes (acceleration, 3D rendering, once)
  • Renderer process (the newly opened page rendering process)

illustrate

Render process (browser rendering process)

Thread : the thread contained within each process, thread is the smallest unit of CPU scheduling (threads is to establish a program unit run on the basis of the process, a process can have multiple threads);

  • GUI rendering thread
  • JavaScript engine thread
  • Timing trigger thread (macro task (asynchronous task))
  • Event trigger thread (macro task (asynchronous task))
  • Asynchronous http request thread (macro task (asynchronous task))
    browser rendering process: https://juejin.im/post/5a6547d0f265da3e283a1df7#heading-6

1. GUI rendering thread

  • Resolving generate HTML DOM tree - rendering engine first parses the HTML document, generate a DOM tree
  • 2. Construction Render tree - either the next inline, embedded or incorporated outreach formula CSS style CSSOM generated parse tree is generated for rendering a tree further based on the DOM tree and the tree CSSOM - render tree ( Render tree),
  • 3. Render tree layout - for each node and performs layout processing the render tree to determine the display position on the screen
  • 4. Draw Render tree - the last tree traversal and rendering UI rear layer with each node plotted

2. JavaScript engine thread (the main thread execution stack)

永远只有JS引擎(JS内核)线程在执行JS脚本程序,
负责解析执行Javascript脚本程序的主线程(例如V8引擎)
  • js engine execution order
  • Macro task (task synchronization) direct execution, other threads to enter the job queue waiting to be executed
  • Then the task queue to perform micro tasks (only asynchronous task)
  • Then execute the macro tasks (asynchronous task) (if there is within the mandate also includes macro task (task synchronization), and so continue to perform 1)

3. GUI rendering thread and the thread mutually exclusive JS engine

由于JavaScript是可操纵DOM的,如果在修改这些元素属性同时渲染界面(即JS线程和UI线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。
因此为了防止渲染出现不可预期的结果,浏览器设置GUI渲染线程与JS引擎为互斥的关系,当JS引擎执行时GUI线程会被挂起,GUI更新则会被保存在一个队列中等到JS引擎线程空闲时立即被执行。

单线程与多线程

单线程语言:JavaScript 的设计就是为了处理浏览器网页的交互(DOM操作的处理、UI动画等),决定了它是一门单线程语言。【处理任务是一件接着一件处理,从上往下顺序执行】

如果有多个线程,它们同时在操作 DOM,那网页将会一团糟。

当遇到计时器、DOM事件监听或者是网络请求的任务时,JS引擎会将它们直接交给** webapi,也就是浏览器提供的相应线程(如定时器线程为setTimeout计时、异步http请求线程处理网络请求)去处理,而JS引擎线程继续后面的其他任务,这样便实现了异步非阻塞**。

同步与异步

JavaScript 中有同步代码与异步代码。

  • 同步:会依次执行,执行完了后便会返回结果
  • 异步:网络请求、计时器、DOM时间监听...

事件循环(event loop)和消息队列(task queue)

  • 事件循环 机制和 消息队列 的维护是由事件触发线程控制的。
  • JS引擎线程遇到异步(DOM事件监听、网络请求、setTimeout计时器等...),会交给相应的线程单独去维护异步任务,等待某个时机(计时器结束、网络请求成功、用户点击DOM),然后由事件触发线程将异步对应的回调函数加入到消息队列中,消息队列中的回调函数等待被执行。
  • 同时,JS引擎线程会维护一个执行栈,同步代码会依次加入执行栈然后执行,结束会退出执行栈。
  • 如果执行栈里的任务执行完成,即执行栈为空的时候(即JS引擎线程空闲),事件触发线程才会从消息队列取出一个任务(即异步的回调函数)放入执行栈中执行。
  • 执行完了后,执行栈再次为空,事件触发线程会重复上一步操作,再取出一个消息队列中的任务,这种机制就被称为事件循环(event loop)机制。

宏任务与微任务

宏任务(macrotask)

  • 定时触发器线程(宏任务(异步任务))
  • setTimeout
  • setInterval
  • setImmediate
  • requestAnimationFrame
  • 事件触发线程(宏任务(异步任务))
  • 异步http请求线程(宏任务(异步任务))
  • script方法(宏任务(同步任务))
  • new Promise(宏任务(同步任务)) 立即执行

微任务(microtask)

由于Es6 和node出现产生的微任务

  • Promise.then() catch() finally(),一旦一个pormise有了结果,回调产生一个微任务
  • process.nextTick
  • MutationObserver

执行机制

  • 1. 执行一个宏任务(栈中没有就从事件队列中获取)
  • 2. 执行过程中如果遇到微任务,就将它添加到微任务的任务队列中
  • 3. 宏任务执行完毕后,立即执行当前微任务队列中的所有微任务(依次执行)
  • 4. 当前宏任务执行完毕,开始检查渲染,然后GUI线程接管渲染
  • 5. 渲染完毕后,JS引擎线程继续,开始下一个宏任务(从宏任务队列中获取)
console.log('script start')
setTimeout(function() {
    console.log('timer over')
}, 0)
Promise.resolve().then(function() {
    console.log('promise1')
}).then(function() {
    console.log('promise2')
})
console.log('script end')
// script start
// script end
// promise1
// promise2
// timer over

JS execution of the main thread first engine block.

Every execution of code stack is a macro to perform tasks, including task queue (macro task queue) because the macro task execution stack of completed tasks will fetch queue (macro task queue) to join in the task execution stack, that is also a mechanism for event loop.

Promise encountered in the implementation of the macro tasks, creates micro-tasks (.then () inside the callback), and added to the micro-task queue the tail.

microtask must be created when a macro task execution, and a macro task before beginning of the next, the browser will re-render the page (task >> >> rendered under a task (take a job from the queue)). Meanwhile, after the completion of a macro task execution, before the rendering of the page, you will perform all tasks of the current micro-micro-tasks in the queue.

That is, in a certain macrotask executed, all microtask before re-rendering and start the next macro task, they will be produced during its execution were completed (before rendering).

This can be explained "promise 1" "promise 2" in the "timer over" before printing. "Promise 1" "promise 2" is added to the task as the micro-micro-task queue, and "timer over" macro as a macro task is added to the job queue, while they are waiting to be executed, but all the micro-micro-task queue task will have been completed prior to the implementation of a macro task in the beginning.

在node环境下,process.nextTick的优先级高于Promise,也就是说:在宏任务结束后会先执行微任务队列中的nextTickQueue,然后才会执行微任务中的Promise。

These examples thoroughly understand the package you have mastered the knowledge js execution order and promise:
https://www.jianshu.com/p/e585e737fb6f

Guess you like

Origin www.cnblogs.com/sunidol/p/11301785.html