视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
js中的event-loop的详细介绍(图文)
2020-11-27 19:31:53 责编:小采
文档
 本篇文章给大家带来的内容是关于js中的event-loop的详细介绍(图文) ,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

浏览器渲染

从耗时的角度,浏览器请求、加载、渲染一个页面,时间花在下面五件事情上:
1.DNS 查询
2.TCP 连接
3.HTTP 请求即响应
4.服务器响应
5.客户端渲染

这里重点讨论第五个部分,即浏览器对内容的渲染,这一部分(渲染树构建,布局和绘制),又可以分为下面的五个部分。

1.处理 HTML 标记并构建 DOM 树。
2.处理 CSS 标记并构建 CSSOM 树。
3.将 DOM 与 CSSOM 合并成一个渲染树。
4.根据渲染树来布局,以计算每个节点的几何信息。
5.将各个节点绘制到屏幕上。

这些并不是本文正文,只是说在完成以上过程之后,整个页面就已经出来了,这个时候浏览器是否就已经处于空闲状态了呢(不考虑动画、交互等处理)?接下来就是本文的重点了。

堆、栈、队列

了解重点之前我们先了解一点简单的基础知识,堆、栈、队列;

对象被分配在一个堆中,即用以表示一个大部分非结构化的内存区域。

这是在程序运行时需要给对new操作产生的对象分配存储空间,是一个没有特别的存储空间。

函数调用形成一个栈帧;

栈的特点:先进后出(First in, last out)函数执行栈过程;可以看成是每次函数first运行时,将函数入栈,此时函数中的其他运行函数(second函数)需要再次入栈,执行完该second函数之后,该second函数将会出栈,继而完成first的执行,执行完成后,first将会出栈;

队列

队列是一种和栈不一样的数据结构,类似管道,先进入的将会现出来,和栈是相反的。

event-loop

javascript从诞生之日起就是一门单线程的非阻塞的脚本语言。这是由其最初的用途来决定的:与浏览器交互。
单线程意味着,javascript代码在执行的任何时候,都只有一个主线程来处理所有的任务。
而非阻塞则是当代码需要进行一项异步任务(无法立刻返回结果,需要花一定时间才能返回的任务,如I/O事件)的时候,主线程会挂起(pending)这个任务,然后在异步任务返回结果的时候再根据一定规则去执行相应的回调。
单线程是必要的,也是javascript这门语言的基石,原因之一在其最初也是最主要的执行环境——浏览器中,我们需要进行各种各样的dom操作。试想一下 如果javascript是多线程的,那么当两个线程同时对dom进行一项操作,例如一个向其添加事件,而另一个删除了这个dom,此时该如何处理呢?因此,为了保证不会 发生类似于这个例子中的情景,javascript选择只用一个主线程来执行代码,这样就保证了程序执行的一致性。
当然,现如今人们也意识到,单线程在保证了执行顺序的同时也了javascript的效率,因此开发出了web worker技术。这项技术号称让javascript成为一门多线程语言。
然而,使用web worker技术开的多线程有着诸多,例如:所有新线程都受主线程的完全控制,不能执行。这意味着这些“线程” 实际上应属于主线程的子线程。另外,这些子线程并没有执行I/O操作的权限,只能为主线程分担一些诸如计算等任务。所以严格来讲这些线程并没有完整的功能,也因此这项技术并非改变了javascript语言的单线程本质。
可以预见,未来的javascript也会一直是一门单线程的语言。

那么为了能够很好地提高的脚本的效率,故而设计的时候有一个非常有趣的特性是事件循环模型,与许多其他语言不同,它永不阻塞。 处理 I/O 通常通过事件和回调来执行,所以当一个应用正等待IndexedDB查询返回或者一个 XHR 请求返回时,它仍然可以处理其它事情,如用户输入。

macro task与micro task

  1. 首先执行script,script被称为全局任务,也属于macrotask;

  2. 当macrotask执行完以下,执行所有的微任务;

  3. 微任务全部执行完,再取任务队列中的一个宏任务执行。

宏任务包括:script, setTimeout, setInterval, setImmediate, I/O,UI rendering,requestAnimationFrame
微任务包括:process.nextTick(node api), 原生Promise(有些实现的promise将then方法放到了宏任务中),Object.observe(已废弃), MutationObserver

执行顺序

所有的宏任务放在一个宏任务队列(即任务队列),处理完一个宏任务(从sccript开始),将微任务队列(包含当时所有的微任务)压入任务队列(宏任务队列)并执行,之后再取下一个任务队列(宏任务)中的宏任务。

下载本文
显示全文
专题