范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

最全从输入URL到浏览器显示页面都发生了什么前端浏览器渲染流程

  面试中常被问到的问题,此问题包含web开发中从前端到后端到运维的绝大多数知识,主要考察面试者知识的广度。本文会根据作者了解的程度增加不断更新,不足之处欢迎评论区补充。
  首先了解一下URL的组成: http://www.baidu.com:8080/news/index.asp?boardID=5&ID=24618&page=1#name
  从上面的URL可以看出,一个完整的URL包括以下几部分:
  1、协议部分:该URL的协议部分为"http:",这代表网页使用的是HTTP协议。在Internet中可以使用多种协议,如HTTP,FTP等等本例中使用的是HTTP协议。在"HTTP"后面的"//"为分隔符
  2、域名部分:该URL的域名部分为"www.baidu.com"。一个URL中,也可以使用IP地址作为域名使用
  3、端口部分:跟在域名后面的是端口,域名和端口之间使用":"作为分隔符。端口不是一个URL必须的部分,如果省略端口部分,将采用默认端口80
  4、虚拟目录部分:从域名后的第一个"/"开始到最后一个"/"为止,是虚拟目录部分。虚拟目录也不是一个URL必须的部分。本例中的虚拟目录是"/news/"
  5、文件名部分:从域名后的最后一个"/"开始到"?"为止,是文件名部分,如果没有"?",则是从域名后的最后一个"/"开始到"#"为止,是文件部分,如果没有"?"和"#",那么从域名后的最后一个"/"开始到结束,都是文件名部分。本例中的文件名是"index.asp"。文件名部分也不是一个URL必须的部分,如果省略该部分,则使用默认的文件名
  6、锚部分:从"#"开始到最后,都是锚部分。本例中的锚部分是"name"。锚部分也不是一个URL必须的部分
  7、参数部分:从"?"开始到"#"为止之间的部分为参数部分,又称搜索部分、查询部分。本例中的参数部分为"boardID=5&ID=24618&page=1"。参数可以允许有多个参数,参数与参数之间用"&"作为分隔符。 URL的输入到浏览器解析的一系列事件
  很多大公司面试喜欢问这样一道面试题, 输入URL到看见页面发生了什么?  ,今天我们来总结一下。 简单来说,共有以下几个过程 DNS解析 发起TCP连接 发送HTTP请求 服务器处理请求并返回HTTP报文 浏览器解析渲染页面 连接结束。
  下面我们来看看具体的细节 通过DNS解析域名的实际IP地址
  发送至 DNS 服务器并获得域名对应的 WEB 服务器的 ip 地址。
  DNS 解析首先会从你的浏览器的缓存中去寻找是否有这个网址对应的 IP 地址,如果没有就向OS系统的 DNS 缓存中寻找,如果没有就是路由器的 DNS 缓存, 如果没有就是 ISP 的DNS 缓存中寻找。 所以,缓存的寻找过程就是: 浏览器 -> 系统 -> 路由器 -> ISP。 如果在某一个缓存中找到的话,就直接跳到下一步。 如果都没有找到的话,就会向 ISP 或者公共的域名解析服务发起 DNS 查找请求。这个查找的过程还是一个递归查询的过程。
  输入 www.google.com  网址后,首先在本地的域名服务器中查找,没找到去根域名服务器查找,没有再去 com  顶级域名服务器查找,,如此的类推下去,直到找到IP地址,然后把它记录在本地,供下次使用。大致过程就是 .   -> .com ->  google.com.   ->  www.google.com.  。 (你可能觉得我多写 .,并木有,这个.对应的就是根域名服务器,默认情况下所有的网址的最后一位都是.,既然是默认情况下,为了方便用户,通常都会省略,浏览器在请求DNS的时候会自动加上) DNS优化
  既然已经懂得了解析的具体过程,我们可以看到上述一共经过了N个过程,每个过程有一定的消耗和时间的等待,因此我们得想办法解决一下这个问题! DNS缓存
  DNS存在着多级缓存,从离浏览器的距离排序的话,有以下几种: 浏览器缓存,系统缓存,路由器缓存,IPS服务器缓存,根域名服务器缓存,顶级域名服务器缓存,主域名服务器缓存。
  在你的chrome浏览器中输入:chrome://dns/,你可以看到chrome浏览器的DNS缓存。
  系统缓存主要存在/etc/hosts(Linux系统)中
  检查浏览器是否有缓存
  通过 Cache-Control  和 Expires  来检查是否命中强缓存,命中则直接取本地磁盘的html(状态码为200 from disk(or memory) cache,内存or磁盘);
  如果没有命中强缓存,则会向服务器发起请求(先进行下一步的TCP连接),服务器通过 Etag  和 Last-Modify  来与服务器确认返回的响应是否被更改(协商缓存),若无更改则返回状态码(304 Not Modified),浏览器取本地缓存;
  若强缓存和协商缓存都没有命中则返回请求结果。 DNS负载均衡
  不知道你们有没有注意这样一件事,你访问http://baidu.com的时候,每次响应的并非是同一个服务器(IP地址不同),一般大公司都有成百上千台服务器来支撑访问,假设只有一个服务器,那它的性能和存储量要多大才能支撑这样大量的访问呢?DNS可以返回一个合适的机器的IP给用户,例如可以根据每台机器的负载量,该机器离用户地理位置的距离等等,这种过程就是DNS负载均衡 与 WEB 服务器建立 TCP 连接。
  TCP 协议通过三次握手建立连接。 客户端通过  SYN   报文段发送连接请求,确定服务端是否开启端口准备连接。状态设置为  SYN_SEND  ; 服务器如果有开着的端口并且决定接受连接,就会返回一个  SYN+ACK   报文段给客户端,状态设置为  SYN_RECV  ; 客户端收到服务器的  SYN+ACK   报文段,向服务器发送  ACK   报文段表示确认。此时客户端和服务器都设置为  ESTABLISHED   状态。连接建立,可以开始数据传输了。
  翻译成大白话就是: 客户端 :你能接收到我的消息吗? 服务端 :可以的,那你能接收到我的回复吗? 客户端 :可以,那我们开始聊正事吧。
  为什么是3次? :避免历史连接,确认客户端发来的请求是这次通信的人。
  为什么不是4次? :3次够了第四次浪费
  建立连接的过程是利用客户服务器模式,假设主机A为客户端,主机B为服务器端。
  采用三次握手是为了防止失效的连接请求报文段突然又传送到主机B,因而产生错误。失效的连接请求报文段是指:主机A发出的连接请求没有收到主机B的确认,于是经过一段时间后,主机A又重新向主机B发送连接请求,且建立成功,顺序完成数据传输。考虑这样一种特殊情况,主机A第一次发送的连接请求并没有丢失,而是因为网络节点导致延迟达到主机B,主机B以为是主机A又发起的新连接,于是主机B同意连接,并向主机A发回确认,但是此时主机A根本不会理会,主机B就一直在等待主机A发送数据,导致主机B的资源浪费。
  采用两次握手不行,原因就是上面说的失效的连接请求的特殊情况。而在三次握手中, client和server都有一个发syn和收ack的过程, 双方都是发后能收, 表明通信则准备工作OK.
  为什么不是四次握手呢? 大家应该知道通信中著名的蓝军红军约定, 这个例子说明, 通信不可能100%可靠, 而上面的三次握手已经做好了通信的准备工作, 再增加握手, 并不能显著提高可靠性, 而且也没有必要。 三次握手
  第一次握手 :
  客户端发送syn包(Seq=x)到服务器,并进入SYN_SEND状态,等待服务器确认;
  第二次握手:
  服务器收到syn包,必须确认客户的SYN(ack=x+1),同时自己也发送一个SYN包(Seq=y),即SYN+ACK包,此时服务器进入SYN_RECV状态;
  第三次握手:
  客户端收到服务器的SYN ACK包,向服务器发送确认包ACK(ack=y+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
  握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。 若协议是https则会做加密
  HTTPS = HTTP + 加密 + 认证 + 完整性保护
  要先申请CA证书,并安装在服务器上(一个文件,配置nginx支持监听443端口开启ssl并设置证书路径)
  浏览器发送请求;
  网站从浏览器发过来的加密规则中选一组自身也支持的加密算法和hash算法,并向浏览器发送带有公钥的证书,当然证书还包含了很多信息,如网站地址、证书的颁发机构、过期时间等。
  浏览器解析证书。
  验证证书的合法性。如颁发机构是否合法、证书中的网站地址是否与访问的地址一致,若不合法,则浏览器提示证书不受信任,若合法,浏览器会显示一个小锁头。
  若合法,或用户接受了不合法的证书,浏览器会生成一串随机数的密码(即密钥),并用证书中提供的公钥加密。
  使用约定好的hash计算握手消息,并使用生成的随机数(即密钥)对消息进行加密,最后将之前生成的所有消息一并发送给网站服务器。
  网站服务器解析消息。用已有的私钥将密钥解密出来,然后用密钥解密发过来的握手消息,并验证是否跟浏览器传过来的一致。然后再用密钥加密一段握手消息,发送给浏览器。
  浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。这里浏览器与网站互相发送加密的握手消息并验证,目的是为了保证双方都获得了一致的密码,并且可以正常的加密解密数据,为后续真正数据的传输做一次测试。
  发送HTTP请求
  首先科补一个小知识,HTTP的端口为80/8080,而HTTPS的端口为443
  发送HTTP请求的过程就是构建HTTP请求报文并通过TCP协议中发送到服务器指定端口 请求报文由 请求行 , 请求抱头 , 请求正文 组成。
  请求行
  请求行的格式为 Method Request-URL HTTP-Version CRLF    eg: GET index.html HTTP/1.1   常用的方法有:  GET  ,  POST  ,  PUT  ,  DELETE  ,  OPTIONS  ,  HEAD  。
  常见的请求方法区别
  这里主要展示 POST  和 GET  的区别
  常见的区别
  GET在浏览器回退时是无害的,而POST会再次提交请求。 GET产生的URL地址可以被Bookmark,而POST不可以。 GET请求会被浏览器主动cache,而POST不会,除非手动设置。 GET请求只能进行url编码,而POST支持多种编码方式。 GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。 GET请求在URL中传送的参数是有长度限制的,而POST么有。 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。 GET比POST更不安全,因为参数直接暴露在URL上,所以不能用来传递敏感信息。 GET参数通过URL传递,POST放在Request body中。
  注意一点你也可以在GET里面藏body,POST里面带参数
  重点区别
  GET  会产生一个 TCP  数据包,而 POST  会产生两个 TCP  数据包。
  详细的说就是: 对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据); 而对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
  注意一点,并不是所有的浏览器都会发送两次数据包,Firefox就发送一次
  请求报头
  请求报头允许客户端向服务器传递请求的附加信息和客户端自身的信息。
  从图中可以看出,请求报头中使用了Accept, Accept-Encoding, Accept-Language, Cache-Control, Connection, Cookie等字段。Accept用于指定客户端用于接受哪些类型的信息,Accept-Encoding与Accept类似,它用于指定接受的编码方式。Connection设置为Keep-alive用于告诉客户端本次HTTP请求结束之后并不需要关闭TCP连接,这样可以使下次HTTP请求使用相同的TCP通道,节省TCP连接建立的时间。
  请求正文
  当使用POST, PUT等方法时,通常需要客户端向服务器传递数据。这些数据就储存在请求正文中。在请求包头中有一些与请求正文相关的信息,例如: 现在的Web应用通常采用Rest架构,请求的数据格式一般为json。这时就需要设置 Content-Type: application/json  。
  更重要的事情-HTTP缓存
  HTTP属于客户端缓存,我们常认为浏览器有一个缓存数据库,用来保存一些静态文件,下面我们分为以下几个方面来简单介绍HTTP缓存 缓存的规则 缓存的方案 缓存的优点 不同刷新的请求执行过程
  缓存的规则
  缓存规则分为 强制缓存 和 协商缓存
  强制缓存
  当缓存数据库中有客户端需要的数据,客户端直接将数据从其中拿出来使用(如果数据未失效),当缓存服务器没有需要的数据时,客户端才会向服务端请求。
  协商缓存
  又称对比缓存。客户端会先从缓存数据库拿到一个缓存的标识,然后向服务端验证标识是否失效,如果没有失效服务端会返回304,这样客户端可以直接去缓存数据库拿出数据,如果失效,服务端会返回新的数据
  强制缓存
  对于强制缓存,服务器响应的header中会用两个字段来表明——Expires和Cache-Control。
  Expires
  Exprires的值为服务端返回的数据到期时间。当再次请求时的请求时间小于返回的此时间,则直接使用缓存数据。但由于服务端时间和客户端时间可能有误差,这也将导致缓存命中的误差,另一方面,Expires是HTTP1.0的产物,故现在大多数使用Cache-Control替代。
  Cache-Control
  Cache-Control有很多属性,不同的属性代表的意义也不同。 private:客户端可以缓存 public:客户端和代理服务器都可以缓存 max-age=t:缓存内容将在t秒后失效 no-cache:需要使用协商缓存来验证缓存数据 no-store:所有内容都不会缓存。
  协商缓存
  协商缓存需要进行对比判断是否可以使用缓存。浏览器第一次请求数据时,服务器会将缓存标识与数据一起响应给客户端,客户端将它们备份至缓存中。再次请求时,客户端会将缓存中的标识发送给服务器,服务器根据此标识判断。若未失效,返回304状态码,浏览器拿到此状态码就可以直接使用缓存数据了。
  对于协商缓存来说,缓存标识我们需要着重理解一下,下面我们将着重介绍它的两种缓存方案。
  Last-Modified
  Last-Modified:服务器在响应请求时,会告诉浏览器资源的最后修改时间。 if-Modified-Since  :浏览器再次请求服务器的时候,请求头会包含此字段,后面跟着在缓存中获得的最后修改时间。服务端收到此请求头发现有if-Modified-Since,则与被请求资源的最后修改时间进行对比,如果一致则返回304和响应报文头,浏览器只需要从缓存中获取信息即可。
  从字面上看,就是说:从某个时间节点算起,是否文件被修改了 如果真的被修改:那么开始传输响应一个整体,服务器返回:200 OK 如果没有被修改:那么只需传输响应header,服务器返回:304 Not Modified if-Unmodified-Since  :从字面上看, 就是说: 从某个时间点算起, 是否文件没有被修改 如果没有被修改:则开始`继续"传送文件: 服务器返回: 200 OK 如果文件被修改:则不传输,服务器返回: 412 Precondition failed (预处理错误)
  这两个的区别是一个是修改了才下载一个是没修改才下载。
  Last-Modified 说好却也不是特别好,因为如果在服务器上,一个资源被修改了,但其实际内容根本没发生改变,会因为Last-Modified时间匹配不上而返回了整个实体给客户端(即使客户端缓存里有个一模一样的资源)。为了解决这个问题,HTTP1.1推出了Etag。
  Etag
  Etag:服务器响应请求时,通过此字段告诉浏览器当前资源在服务器生成的唯一标识(生成规则由服务器决定) If-None-Match:再次请求服务器时,浏览器的请求报文头部会包含此字段,后面的值为在缓存中获取的标识。服务器接收到次报文后发现If-None-Match则与被请求资源的唯一标识进行对比。 不同,说明资源被改动过,则响应整个资源内容,返回状态码200。 相同,说明资源无心修改,则响应header,浏览器直接从缓存中获取数据信息。返回状态码304.
  但是实际应用中由于Etag的计算是使用算法来得出的,而算法会占用服务端计算的资源,所有服务端的资源都是宝贵的,所以就很少使用Etag了。
  缓存的优点 减少了冗余的数据传递,节省宽带流量 减少了服务器的负担,大大提高了网站性能 加快了客户端加载网页的速度 这也正是HTTP缓存属于客户端缓存的原因。
  不同刷新的请求执行过程
  浏览器地址栏中写入URL,回车 浏览器发现缓存中有这个文件了,不用继续请求了,直接去缓存拿。(最快)
  F5 F5就是告诉浏览器,别偷懒,好歹去服务器看看这个文件是否有过期了。于是浏览器就战战兢兢的发送一个请求带上If-Modify-since。
  Ctrl+F5 告诉浏览器,你先把你缓存中的这个文件给我删了,然后再去服务器请求个完整的资源文件下来。于是客户端就完成了强行更新的操作.
  服务器处理请求并返回HTTP报文
  它会对TCP连接进行处理,对HTTP协议进行解析,并按照报文格式进一步封装成HTTP Request对象,供上层使用。这一部分工作一般是由Web服务器去进行,我使用过的Web服务器有Tomcat, Nginx和Apache等等 HTTP报文也分成三份, 状态码  , 响应报头 和 响应报文
  状态码
  状态码是由3位数组成,第一个数字定义了响应的类别,且有五种可能取值: 1xx:指示信息–表示请求已接收,继续处理。 2xx:成功–表示请求已被成功接收、理解、接受。 3xx:重定向–要完成请求必须进行更进一步的操作。 4xx:客户端错误–请求有语法错误或请求无法实现。 5xx:服务器端错误–服务器未能实现合法的请求。
  平时遇到比较常见的状态码有:200, 204, 301, 302, 304, 400, 401, 403, 404, 422, 500
  常见状态码区别
  200 成功
  请求成功,通常服务器提供了需要的资源。
  204 无内容
  服务器成功处理了请求,但没有返回任何内容。
  301 永久移动
  请求的网页已永久移动到新位置。 服务器返回此响应(对 GET 或 HEAD 请求的响应)时,会自动将请求者转到新位置。
  302 临时移动
  服务器目前从不同位置的网页响应请求,但请求者应继续使用原有位置来进行以后的请求。
  304 未修改
  自从上次请求后,请求的网页未修改过。 服务器返回此响应时,不会返回网页内容。
  400 错误请求
  服务器不理解请求的语法。
  401 未授权
  请求要求身份验证。 对于需要登录的网页,服务器可能返回此响应。
  403 禁止
  服务器拒绝请求。
  404 未找到
  服务器找不到请求的网页。
  422 无法处理
  请求格式正确,但是由于含有语义错误,无法响应
  500 服务器内部错误
  服务器遇到错误,无法完成请求。
  响应报头
  常见的响应报头字段有: Server, Connection...。
  响应报文
  你从服务器请求的HTML,CSS,JS文件就放在这里面 浏览器解析渲染页面
  就是 Webkit  解析渲染页面的过程。 解析HTML形成DOM树 解析CSS形成CSSOM 树 合并DOM树和CSSOM树形成渲染树 浏览器开始渲染并绘制页面
  这个过程涉及两个比较重要的概念 回流 和 重绘 ,DOM结点都是以盒模型形式存在,需要浏览器去计算位置和宽度等,这个过程就是回流。等到页面的宽高,大小,颜色等属性确定下来后,浏览器开始绘制内容,这个过程叫做重绘。浏览器刚打开页面一定要经过这两个过程的,但是这个过程非常非常非常消耗性能,所以我们应该尽量减少页面的回流和重绘 浏览器解析执行js脚本
  这个过程中可能会有dom操作、ajax发起的http网络请求等。 浏览器发起网络请求
  web-socket、ajax等,这个过程通常是为了获取数据 服务器响应ajax请求ajax请求在到达真正的server之前,可能还会经过网关全线校验、消息队列或nginx等负载均衡处理 到达server后,后端会解析http请求报文,得到url、请求参数、http头、cookie等等信息 登录校验、权限校验(cookie校验、jwt权限校验等) 可能会查询数据库,进行常用的CRUD(增删改查)等操作 返回响应数据 浏览器处理事件循环等异步逻辑。
  setTimeout、setInterval、Promise等宏任务、微任务队列 性能优化之回流重绘回流
  当Render Tree中部分或全部元素的尺寸、结构、或某些属性发生改变时,浏览器重新渲染部分或全部文档的过程称为回流。
  会导致回流的操作: 页面首次渲染 浏览器窗口大小发生改变 元素尺寸或位置发生改变 元素内容变化(文字数量或图片大小等等) 元素字体大小变化 添加或者删除可见的DOM元素 激活CSS伪类(例如::hover) 查询某些属性或调用某些方法
  一些常用且会导致回流的属性和方法: clientWidth、clientHeight、clientTop、clientLeft  offsetWidth、offsetHeight、offsetTop、offsetLeft  scrollWidth、scrollHeight、scrollTop、scrollLeft  scrollIntoView()、scrollIntoViewIfNeeded()  getComputedStyle()  getBoundingClientRect()  scrollTo()  重绘
  当页面中元素样式的改变并不影响它在文档流中的位置时(例如:color、background-color、visibility等),浏览器会将新样式赋予给元素并重新绘制它,这个过程称为重绘。 优化CSS避免使用table布局。 尽可能在DOM树的最末端改变class。 避免设置多层内联样式。 将动画效果应用到position属性为absolute或fixed的元素上。 避免使用CSS表达式(例如:calc())。 JavaScript避免频繁操作样式,最好一次性重写style属性,或者将样式列表定义为class并一次性更改class属性。 避免频繁操作DOM,创建一个documentFragment,在它上面应用所有DOM操作,最后再把它添加到文档中。 也可以先为元素设置display: none,操作结束后再把它显示出来。因为在display属性为none的元素上进行的DOM操作不会引发回流和重绘。 避免频繁读取会引发回流/重绘的属性,如果确实需要多次使用,就用一个变量缓存起来。 对具有复杂动画的元素使用绝对定位,使它脱离文档流,否则会引起父元素及后续元素频繁回流。 JS的解析
  JS的解析是由浏览器的JS引擎完成的。由于JavaScript是单线程运行,也就是说一个时间只能干一件事,干这件事情时其他事情都有排队,但是有些人物比较耗时(例如IO操作),所以将任务分为 同步任务 和 异步任务 ,所有的同步任务放在主线程上执行,形成执行栈,而异步任务等待,当执行栈被清空时才去看看异步任务有没有东西要搞,有再提取到主线程执行,这样往复循环(冤冤相报何时了,阿弥陀佛),就形成了Event Loop事件循环,下面来看看大人物 Event Loop
  先看一段代码 setTimeout(function(){     console.log("定时器开始啦") });  new Promise(function(resolve){     console.log("马上执行for循环啦");     for(var i = 0; i < 10000; i++){         i == 99 && resolve();     } }).then(function(){     console.log("执行then函数啦") });  console.log("代码执行结束");
  结果我想大家都应该知道。主要来介绍JavaScript的解析,至于Promise等下一节再说 JavaScript
  JavaScript是一门单线程语言,尽管H5中提出了 Web-Worker  ,能够模拟实现多线程,但本质上还是单线程,说它是多线程就是扯淡。 事件循环
  既然是单线程,每个事件的执行就要有顺序,比如你去银行取钱,前面的人在进行,后面的就得等待,要是前面的人弄个一两个小时,估计后面的人都疯了,因此,浏览器的JS引擎处理JavaScript时分为 同步任务 和 异步任务
  这张图我们可以清楚看到 同步和异步任务分别进入不同的执行"场所",同步的进入主线程,异步的进入Event Table并注册函数。 当指定的事情完成时,Event Table会将这个函数移入Event Queue。 主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。 上述过程会不断重复,也就是常说的Event Loop(事件循环)。
  js引擎存在monitoring process进程,会持续不断的检查主线程执行栈是否为空,一旦为空,就会去Event Queue那里检查是否有等待被调用的函数。 估计看完这些你对事件循环有一定的了解,但是事实上我们看对的没这么简单,通常我们会看到Promise,setTimeout,process.nextTick(),这个时候你和我就懵逼。
  除了同步任务和异步任务,我们还分为宏任务和微任务,常见的有以下几种 macro-task(宏任务):包括整体代码script,setTimeout,setInterval micro-task(微任务):Promise,process.nextTick
  不同任务会进入不同的任务队列来执行。 JS引擎开始工作后,先在宏任务中开始第一次循环( script里面先执行,不过我喜欢把它拎出来,直接称其进入执行栈  ),当主线程执行栈全部任务被清空后去微任务看看,如果有等待执行的任务,执行全部的微任务(其实将其回调函数推入执行栈来执行),再去宏任务找最先进入队列的任务执行,执行这个任务后再去主线程执行任务(例如执行```console.log("hello world")这种任务),执行栈被清空后再去微任务,这样往复循环(冤冤相报何时了)
  Tip:微任务会全部执行,而宏任务会一个一个来执行
  下面来看一段代码 setTimeout(function() {     console.log("setTimeout"); })  new Promise(function(resolve) {     console.log("promise");     resolve(); }).then(function() {     console.log("then"); })  console.log("console");
  我们看看它的执行情况 第一轮 这段代码进入主线程 遇到setTimeout,将其回调函数注册后分发到宏任务 第二轮 遇到Promise,new Promise立即执行(这个不解释,想了解的我后续文章会介绍),输出 promise  ,遇到 then  ,将其分发到微任务 第三轮 遇到 console.log("console")  ,直接输出 console  第四轮 主线程执行栈已经清空,先去微任务看看,执行then函数,输出 then  第五轮 微任务执行完了,看看宏任务,有个setTimeout,输出 setTimeout  ,整体执行完毕。
  具体的执行过程大致就是这样。

新款少女服装轻盈的少女,若天仙若轻盈的蝴蝶若女神,带着活力,带着阳光,带着夏日的草地向我们走来。看到这一身服装配,在少女身上,我们首先想到的是电影围城里的那位由史兰芽主演的少女。围城之所以那么那年那时四大件手表缝纫机自行车收音机,在上世纪七十年代称为三转一响,属于大件。说是大件,指的是那个年代,随便一件的价格,便是普通百姓一人一年以上的生活费用,在当时是奢侈品。苏联手表我1972年由温柔干净文案精选20句1爱自己是终身浪漫的开始。2与其互为人间,不如自成宇宙。3我不知道将去何方,但我已在路上。4心里的火永远不要灭,哪怕别人只能看到烟。5陪你看日落的人比日落更浪漫。6好不容易上了岸,家庭教育小妙招图说智慧父母(五十)家庭父母x智慧教育疫情期间亲子关系十问答(下)06防疫在家,不知道怎样和宝贝在家运动,怎么办?建议您必须知道的亲子活动黄金五法则。法则一不同年龄的孩子适合的运动不一样6岁之前,大部值得收藏一键解锁铁路小常识,原来火车还有这些秘密2022年518国际博物馆日即将到来,今年的主题是博物馆的力量(ThePowerofMuseums)。国际博协对该主题进行了阐释,即博物馆有能力改变我们周围的世界。博物馆作为一个联一味祛湿神汤,仅4味!痰湿结节体质的人不可错过,请收藏今天,我们再来说说痰湿。痰湿缠身,百病生!给结节患者说一个化痰祛瘀的古方,调全身於堵痰湿体质的人从外观上表现为体型肥胖,腹部肥满松软,面部油脂较多,面色淡黄而暗,容易出汗或困倦,喜新型清洁能源时代即将到来,现代氢燃料电池车NEXO4月初,一则看似不起眼的消息现代汽车氢燃料电池车NEXO中国版获牌照,在中国乘用车市场引起不小波澜。这是现代汽车首款符合中国法规的氢燃料电池乘用车,目前已允许合法上路,这对中国氢能世界上有一种蓝,叫赛里木湖!最全攻略在此,建议收藏赛里木湖这里位于新疆西部,背靠雪山,湖边是广阔的草原,湖水清澈蔚蓝,风光美不胜收,是新疆知名的几大景点之一。这里是大西洋暖湿气流最后眷顾的地方,因此也被称为大西洋的最后一滴眼泪。世质用车关于增驾C6你想了解的都在这里随着自驾游的兴起以及多元化用车的流行趋势,开着房车去旅行已经成为了这个时代最惬意的生活方式。而单独购买一辆房车不仅需要一笔充足的预算,同时还要考虑到后期用车成本以及停车的问题。所以5月12日直播预告漂洋过海经典互鉴之意大利文艺复兴园林东西方虽相距千里,但各自的园林,都是人们的理想家园。明清时期,中国园林进入集大成时期,而同一时期,意大利文艺复兴台地式园林,揭开了西方近代园林艺术发展的序幕。恢弘神秘的古罗马帝国,乡情散文在春天的田野上撒欢一年里很少有下乡的机会。原因很简单,家越搬离农村老家的距离越远。老屯居住的亲戚,一般大的童娃也越来越少。大多数的人和我一样,成为了城市人,有的人还挤进了一线大城市,比我光彩多了。疫
娱乐圈中的婆媳关系,看一下圈中女明星与婆婆的关系自古以来,都有那么一句话婆媳是天生的敌人,所以从古至今,婆媳关系一直是一个世纪难题,不只是普通人如此,连明星也会有这样的婆媳问题。周杰伦,昆凌周杰伦是娱乐圈出了名的大孝子,因为父母明星不拍戏去带货,身价千万还赚老百姓的钱,这就是现实大家有没有发现,现在带货主播成了一个香饽饽的职业,几乎每天都有数以百计的人投身于直播行业,甚至连明星都纷纷跳下神坛,开始直播带货。难道这才是明星最终的归宿吗?其实对于明星带货这一现走进朝鲜,中国光棍想娶朝鲜老婆,不料导游一句话打消了他的念头走进朝鲜,中国光棍想娶朝鲜老婆,不料导游一句话打消了他的念头!我国有数千万单身男青年,主要集中在农村地区,很多人因为出不起彩礼钱一直未婚。在此前的朝鲜之旅中,同团就有一名单身男青年留队成功!北京首钢三冠王老臣不走了,渴望退役前再拿一座总冠军北京首钢休赛期已经决定清理球队阵容,常林和刘晓宇已经离队,王骁辉也退役了,俱乐部老队员还剩下翟晓川方硕和朱彦西等人。从球队阵容配置来看,这三名老将都不会离队,解立彬要想完成阵容新老杜锋有心无力,中国男篮或将再次输给澳大利亚的5个原因引言男篮世界杯预选赛的比赛已经经过了两场的角逐,中国男篮在第一场面对澳大利亚的比赛中虽然发挥的非常出色,但最终还是因为硬实力的差距而败下阵来,随后我们又毫无悬念的大比分战胜了中国台摘星官宣后,这10座城市火起来了,报复性旅游又要来了摘了,总算是摘了!今天打开朋友圈,很多人都在发这段话,乍一看还以为是家里的瓜果丰收了,原来是工信部宣布6月29日起取消通信行程卡星号标记,这则通告对旅游达人来说是一个好消息,意味着四川这座千年古镇,听名字就很有意境,外来游客知道的并不多一生很短,你要大胆。随着旅游业的不断发展,我们选择外出旅行的方式也越来越多,我们对于旅行的态度也从打卡拍照慢慢的变成慢下来欣赏风景。其实无论是在哪里在做什么,只有静下来慢慢去感受,河北整改极成功的公园,重新开放游客剧增,位于市区中心众所周知,近年来,中国非常重视环境问题。以前因为中国各个领域和世界一流水平都不一样,所以非常重视工农兵商各个领域的发展动向。当时很多公司都是利用环境来进行成长的,不得不说成本非常昂新疆旅游,最经典的3条线路,815天详细日程住宿地景点规划明净清朗的七月,新疆这片遗落在亚洲大陆中心的梦乡,开始迎来一大批徐霞客的丈量足迹。暑期自驾新疆,815天内的行程规划,共有3条最经典的旅游线路。一北疆大环线线路简介人们习惯将新疆分旅游旺季来临,泰国素叻府旅游形势良好7月1日,泰国国家旅游局苏梅岛办公室主任素帕甘女士透露,泰国自今日起正式取消泰国通行证(ThailandPass)系统后,将有效促进素叻府当地旅游。她表示,78月份是泰国湾苏梅岛龟为什么外国人只背包旅游,而中国人却要拖行李箱?和你想的不一样事实上,旅游已经成为一件相对普遍的事情,并且不同国家的人在旅游习惯上有这很大的差异,这些差异实际上是由不同的生活习惯造成的,然后衍生到不同的旅游习惯中。为什么外国人只背包旅行,甚至