JavaScript的事件循环

单线程是JavaScript的一大特点

之所以是单线程,是因为在JavaScript与用户互动,操作dom的时候,如果是多线程(我们同时两个线程对一个dom操作了修改和删除命令,那么该操作的结果遵循的是哪个线程?)会引发很多麻烦的同步问题。

因为是单线程,所有的任务都需要排队。前一个任务结束后才可以执行下一个任务,而后续的任务会不得不“排队”。在我们进行i/o交互的时候,等待时间是非常长的,该段时间的cpu是空闲出来的。因而引出了任务队列

所有的任务可以分为两种,一种是同步任务,一种是异步任务。同步任务如其名,在该队列当中事件必须是顺序执行的。异步任务指的是,不进入主线程,而进入任务队列,只有任务队列通知主线程,这个异步任务可以去执行了,主线程才会去执行它。

(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。

(2)主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。

(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。

(4)主线程不断重复上面的第三步。

任务队列

摘自:JavaScript 运行机制详解:再谈Event Loop - 阮一峰的网络日志

执行栈中的代码(同步任务),总是在读取"任务队列"(异步任务)之前执行。

异步任务又:

  • setTimeout() 设置的异步延迟事件;
  • DOM 操作相关如布局和绘制事件;(这也是为什么dom还没渲染而先执行了之后的alert)
  • 网络 I/O 如 AJAX 请求事件;
  • 用户操作事件,如鼠标点击、键盘敲击。

而任务队列当中,全部都是可以执行的,该结构是一个先进先出的结构,如果可以执行了,那么同步任务执行的就是它的回调函数

(作者@BusyRich)。

Node.js

(1)V8引擎解析JavaScript脚本。

(2)解析后的代码,调用Node API。

(3)libuv库负责Node API的执行。它将不同的任务分配给不同的线程,形成一个Event Loop(事件循环),以异步的方式将任务的执行结果返回给V8引擎。

(4)V8引擎再将结果返回给用户。

宏任务与微任务

任务又可以分为宏任务与微任务

如同筛选一样:

每一轮筛选,我们都会把同步任务执行掉,微任务、宏任务就放两个篮子里等待执行。
筛选完后,我们看一看微任务篮子里有没有东西,有的话拿出来筛选(这个筛选和上一部的筛选一样,因此是循环过程)
微任务篮子选完后,再看看微任务篮子里有没有多出来的任务,有就继续筛选。
完全清理干净微任务后就开始筛选宏任务,注意,宏任务就筛一趟,不管会不会多出新的宏任务
故:有微则微,无宏才实


————————————————
版权声明:本文为CSDN博主「CSDN_Yong」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/CSDN_Yong/article/details/104742106

dom渲染的过程:

解析html源码,创建DOM树
浏览器会分析html源码,在DOM树中,每一个HTML标签都有一个对应的节点(元素节点),并且每一个文本也都有一个对应的节点(文本节点)。DOM树的根节点就是documentElement,对应的是html标签。

解析CSS代码,计算样式数据
浏览器会忽略错误的CSS代码,然后根据样式的优先级进行解析,忽略一些选择器的属性,优先级从低到高:浏览器默认设置,用户设置,外联样式,内联样式,行内样式等,这个是有权重的。

构建渲染树
渲染树和DOM树很相似,但是不一样。主要区别是DOM树完全和html标签一一对应,但渲染树会忽略不需要渲染的元素,并且渲染树每个节点会留有CSS样式的数据信息。可以认为DOM+样式数据=渲染树。

绘制
拿到渲染树后,浏览器根据规则表现视觉效果。
————————————————
版权声明:本文为CSDN博主「CSDN_Yong」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/CSDN_Yong/article/details/104742106

再谈alert为什么会导致堵塞而不是顺序先渲染后再执行

alert() 是 window 的内置函数,被认为是同步 CPU代码,所以JavaScript 引擎会优先执行同步代码,alert 弹窗先出现;alert 有特殊的阻塞性质,JavaScript 引擎的执行被阻塞住;点击 alert 的“确定”,JavaScript 没有了阻塞,执行完同步代码后,又读取事件队列里的异步任务(这个时候才发起网络请求)。
————————————————
版权声明:本文为CSDN博主「看云朵敲代码」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41841048/article/details/105498263

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JavaScript事件循环JavaScript中用于处理异步操作的机制。由于JavaScript是单线程的,它无法同时执行多个任务。为了处理异步任务,JavaScript引入了事件循环机制。 事件循环主要由以下几个组成部分: 1. 调用堆栈(Call Stack):用于存储函数调用的记录。当函数被调用时,会将其压入调用堆栈中,当函数执行毕后,会从调用堆栈中弹出。 2. 任务队列(Task Queue):用于存储待处理的异步任务。当异步任务成时,会被添加到任务队列中。 3. 事件循环(Event Loop):负责监听调用堆栈和任务队列的状态,当调用堆栈为空时,会从任务队列中取出任务并执行事件循环的工作流程如下: 1. JavaScript引擎执行同步任务,并将异步任务添加到任务队列中。 2. 当调用堆栈为空时,事件循环会从任务队列中取出一个任务。 3. 取出的任务会被压入调用堆栈中执行。 4. 执行毕后,调用堆栈为空,事件循环继续从任务队列中取出任务执行。 这样循环执行,实现了异步任务的处理。 相关问题: 1. 什么是异步任务?为什么需要处理异步任务? 2. JavaScript如何处理异常? 3. JavaScript中的回调函数是什么?如何使用回调函数处理异步任务? 4. 什么是Promise?如何使用Promise处理异步任务? 5. JavaScript中的定时器有哪些?它们是如何工作的? 6. 什么是事件驱动编程?如何在JavaScript中使用事件驱动编程? 7. JavaScript中的Event Loop与浏览器的渲染机制有什么关系?<span class="em">1</span><span class="em">2</span> #### 引用[.reference_title] - *1* [详解JavaScript事件循环机制](https://download.csdn.net/download/weixin_38694006/13608655)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [浏览器显示数据库中数据的条形图柱状图 前后端分离vue.js+spring boot 计算机软件工程课程设计毕业设计 ...](https://download.csdn.net/download/Amzmks/88275824)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值