摘要:现实中是这样的执行结果为结果告诉我们,是单线程没错,不过不是逐行同步执行。搜索了很多官方个人博客得到了一堆词引擎主线程事件表事件队列宏任务微任务,彻底懵逼。。。以此规则不停的执行下去就是我们所听到的事件循环。
都知道javascript是单线程,那么问题来了,既然是单线程顺序执行,那怎么做到异步的呢?
setTimeout(function() { console.log(1); }); new Promise(function(resolve, reject) { console.log(2) resolve(3) }).then(function(val) { console.log(val); }) console.log(4) //执行结果为 2、4、3、1
结果告诉我们,js是单线程没错,不过不是逐行同步执行。
那我们就来解析一下既然有异步,那顺序是怎样的?这些执行顺序规则就是理解eventLoop的要点,继续往下。
上图为我录制的chrome控制代码台执行顺序,虽然能看出执行顺序但我们还是懵逼的,我们不知道规则,不懂就要问。
搜索了很多官方、个人博客得到了一堆词:js引擎、主线程、事件表、事件队列、宏任务、微任务,彻底懵逼。。。
不急不急一个个来,我们进入刨根问底状态
js引擎总结一句话就是解析优化代码 **制定执行规则 具体规则往下看
主线程总结一句话执行js引擎优化并排列顺序后的代码
事件表(event table)执行代码过程中,异步的回调,例如(setTimeout,ajax回调)注册回调事件到event table
事件队列当事件回调结束,事件表(event table)会将事件移入到事件队列(event queue)
宏任务和微任务事件 | 浏览器 | node |
---|---|---|
I/O | ✅ | ✅ |
setTimeout | ✅ | ✅ |
setInterval | ✅ | ✅ |
setImmediate | ❌ | ✅ |
requestAnimationFrame | ✅ | ❌ |
事件 | 浏览器 | node |
---|---|---|
I/O | ✅ | ✅ |
process.nextTick | ❌ | ✅ |
MutationObserver | ✅ | ❌ |
Promise.then catch finally | ✅ | ✅ |
很多博客是这样说的:
浏览器会不断从task队列中按顺序取task执行,每执行完一个task都会检查microtask队列是否为空(执行完一个task的具体标志是函数执行栈为空),如果不为空则会一次性执行完所有microtask。然后再进入下一个循环去task队列中取下一个task执行
说实话不是太理解,那么我就以自己的方式去学习和理解
为了更好的理解我们再看代码
console.log("1"); setTimeout(function() { console.log("2"); new Promise(function(resolve) { console.log("3"); resolve(); }).then(function() { console.log("4") }) }) new Promise(function(resolve) { console.log("5"); resolve(); }).then(function() { console.log("6") }) setTimeout(function() { console.log("7"); new Promise(function(resolve) { console.log("8"); resolve(); }).then(function() { console.log("9") }) }) //执行结果:1、5、6、2、3、4、7、8、9
有图为证我没骗你
再来个动图我们具体看看浏览器的执行顺序
首先js引擎,区分是直接执行(同步代码),再执行异步代码,如果是异步再区分是宏任务还是微任务,分别放入两个任务队列,然后开始执行,每执行完一个宏任务,扫一遍微任务队列并全部执行,此时形成一次eventLoop循环。以此规则不停的执行下去就是我们所听到的事件循环。
我再补充一点,可以理解js引擎一开始把整个script当做一个宏任务,这样里边的就更容易理解了,开始就执行script宏任务,解析到宏任务里边又包含同步代码和异步代码(宏任务和微任务)依次执行顺序形成eventLoop。
欢迎吐槽点赞评论!
文章参考学习:
https://www.jianshu.com/p/12b...
https://juejin.im/post/59e85e...
https://segmentfault.com/a/11...
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/101063.html
摘要:如果当前没有事件也没有定时器事件,则返回。相关资料关于的架构及设计思路的事件讨论了使用线程池异步运行代码。下一篇初窥事件机制的实现二中定时器的实现 在浏览器中,事件作为一个极为重要的机制,给予JavaScript响应用户操作与DOM变化的能力;在Node.js中,事件驱动模型则是其高并发能力的基础。 学习JavaScript也需要了解它的运行平台,为了更好的理解JavaScript的事...
摘要:事件循环了解了在引擎中是如何工作了之后,来看下如何使用异步回调函数来避免代码。从回调函数被放入后秒钟,把移到中。由于事件循环持续地监测调用栈是否已空,此时它一注意到调用栈空了,就调用并创建一个新的调用栈。 听多了JavaScript单线程,异步,V8,便会很想去知道JavaScript是如何利用单线程来实现所谓的异步的。我参考了一些文章,了解到一个很重要的词汇:事件循环(Event L...
摘要:阶段有两个主要功能也会执行时间定时器到达期望时间的回调函数执行事件循环列表里的函数当进入阶段并且没有其余的定时器,那么如果事件循环列表不为空,则迭代同步的执行队列中的函数。如果没有,则等待回调函数进入队列并立即执行。 Event Loop 本文以 Node.js 为例,讲解 Event Loop 在 Node.js 的实现,原文,JavaScript 中的实现大同小异。 什么是 Eve...
摘要:的宿主最开始本身就是浏览器,处理用户的交互事件。既然是单线程的,那就意味着任务需要排队,只有前一个任务执行完毕,下一个任务才能开始,于是就有了任务队列。事件循环有两种用于浏览上下文的事件循环和用于的事件循环。 最近看到Event Loop这个词出现的频率有点高,于是查阅各方资料在此记录一下。 先不说概念,我们来看段代码: console.log(script start); setT...
js异步历史 一个 JavaScript 引擎会常驻于内存中,它等待着我们把JavaScript 代码或者函数传递给它执行 在 ES3 和更早的版本中,JavaScript 本身还没有异步执行代码的能力,引擎就把代码直接顺次执行了,异步任务都是宿主环境(浏览器)发起的(setTimeout、AJAX等)。 在 ES5 之后,JavaScript 引入了 Promise,这样,不需要浏览器的安排,J...
摘要:曾经的理解首先,是单线程语言,也就意味着同一个时间只能做一件事,那么为什么不是多线程呢这样还能提高效率啊假定同时有两个线程,一个线程在某个节点上编辑了内容,而另一个线程删除了这个节点,这时浏览器就很懵逼了,到底以执行哪个操作呢所以,设计者把 Event Loop曾经的理解 首先,JS是单线程语言,也就意味着同一个时间只能做一件事,那么 为什么JavaScript不是多线程呢?这样还能提...
阅读 1320·2021-09-22 15:09
阅读 2655·2021-08-20 09:38
阅读 2401·2021-08-03 14:03
阅读 863·2019-08-30 15:55
阅读 3368·2019-08-30 12:59
阅读 3550·2019-08-26 13:48
阅读 1885·2019-08-26 11:40
阅读 647·2019-08-26 10:30