Event Loop

来源:http://www.chinese-glasses.com 作者:Web前端 人气:132 发布时间:2020-03-14
摘要:宏任务包括 script,setTimeout,setInterval,setImmediate,I/O,UIrendering。 现在在前端领域各种技术层出不穷,掌握底层原理,可以让自己以不变,应万变。 也就是说,如果await后面跟着Promi

宏任务包括 script,setTimeout,setInterval,setImmediate,I/O,UI rendering。

现在在前端领域各种技术层出不穷,掌握底层原理,可以让自己以不变,应万变。

也就是说,如果await后面跟着Promise的话,async1 end需要等待三个 tick 才能执行到。那么其实这个性能相对来说还是略慢的,所以 V8 团队借鉴了 Node 8 中的一个 Bug,在引擎底层将三次 tick 减少到了二次 tick。但是这种做法其实是违法了规范的,当然规范也是可以更改的,这是 V8 团队的一个 PR,目前已被同意这种做法。

图片 1

console.log('script start')async function async1() { await async2() console.log('async1 end')}async function async2() { console.log('async2 end')}async1()setTimeout(function() { console.log('setTimeout')}, 0)new Promise(resolve = { console.log('Promise') resolve()}) .then(function() { console.log('promise1') }) .then(function() { console.log('promise2') })console.log('script end')// script start = async2 end = Promise = script end = promise1 = promise2 = async1 end = setTimeout

队列的数据元素又称为队列元素。在队列中插入一个队列元素称为入队,从队列删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除,故队列又称为先进先出(FIFO—first in first out)

首先先来解释下上述代码的 async和 await的执行顺序。当我们调用async1函数时,会马上输出async2 end,并且函数返回一个 Promise,接下来在遇到 await 的时候会就让出线程开始执行async1外的代码,所以我们完全可以把await看成是让出线程的标志。

JS调用栈

JS调用栈采用的是后进先出的规则,当函数执行的时候,会被添加到栈的顶部,当执行栈执行完成后,就会从栈顶移出,直到栈内被清空。

然后当同步代码全部执行完毕以后,就会去执行所有的异步代码,那么又会回到await的位置执行返回的Promise的 resolve函数,这又会把resolve丢到微任务队列中,接下来去执行 then中的回调,当两个then中的回调全部执行完毕以后,又会回到await的位置处理返回值,这时候你可以看成是Promise.resolve (返回值).then() ,然后await 后的代码全部被包裹进了then的回调中,所以 console.log(' async1 end ')会优先执行于 setTimeout。

特殊之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作,和一样,队列是一种操作受限制的线性表。

如果你觉得上面这段解释还是有点绕,那么我把 async的这两个函数改造成你一定能理解的代码

如最大堆

注意:新的浏览器中不是如上打印的,因为 await 变快了,具体内容可以往下看

是只能在某一端插入删除特殊线性表

这里很多人会有个误区,认为微任务快于宏任务,其实是错误的。因为宏任务中包括了script,浏览器会先执行一个宏任务,接下来有异步代码的话才会先执行微任务。

进行插入操作的端称为队尾,进行删除操作的端称为队头。 队列中没有元素时,称为空队列

时间: 2019-12-05阅读: 90标签: 线程

前言

不同的任务源会被分配到不同的 Task 队列中,任务源可以分为微任务(microtask) 和宏任务(macrotask)。在 ES6 规范中,microtask 称为 jobs ,macrotask 称为 task 。下面来看以下代码的执行顺序:

MacroTask

script全部代码、setTimeout、setInterval、setImmediate(浏览器暂时不支持,只有IE10支持,具体可见MDN)、I/O、UI Rendering。

所以 Event Loop 执行顺序如下所示:

在JavaScript中,任务被分为两种,一种宏任务(MacroTask)也叫Task,一种叫微任务(MicroTask)。

所以以上代码虽然setTimeout写在Promise之前,但是因为Promise属于微任务而setTimeout属于宏任务,所以会有以上的打印。

事件循环的进程模型

选择当前要执行的任务队列,选择任务队列中最先进入的任务,如果任务队列为空即null,则执行跳转到微任务(MicroTask)的执行步骤。

将事件循环中的任务设置为已选择任务。

执行任务。

将事件循环中当前运行任务设置为null。

将已经运行完成的任务从任务队列中删除。

microtasks步骤:进入microtask检查点。

更新界面渲染。

返回第一步。

new Promise((resolve, reject) = { console.log('async2 end') // Promise.resolve() 将代码插入微任务队列尾部 // resolve 再次插入微任务队列尾部 resolve(Promise.resolve())}).then(() = { console.log('async1 end')})

MicroTask

Process.nextTick、Promise、Object.observe、MutationObserver(具体使用方式查看这里)

Javascript 有一个 main thread 主线程和 call-stack 调用栈,所有的任务都会被放到调用栈等待主线程执行。

本文由10bet发布于Web前端,转载请注明出处:Event Loop

关键词:

上一篇:页面制作中要注意的编码问题

下一篇:没有了

最火资讯