信息产业部备案网站,军事网站大全军事网,网页源代码中什么标记必不可少,网站职能建设论文浏览器和Node的事件循环机制 引言浏览器的事件循环机制 引言
由于JS是单线程的脚本语言#xff0c;所以在同一时间只能做一件事情#xff0c;当遇到多个任务时#xff0c;我们不可能一直等待任务完成#xff0c;这会造成巨大的资源浪费。为了协调时间#xff0c;用户交互… 浏览器和Node的事件循环机制 引言浏览器的事件循环机制 引言
由于JS是单线程的脚本语言所以在同一时间只能做一件事情当遇到多个任务时我们不可能一直等待任务完成这会造成巨大的资源浪费。为了协调时间用户交互脚本还有UI渲染和网络处理等行为防止主线程阻塞才有了事件循环。而事件循环其实就是一种机制它会不断的轮询任务队列并将队列中的任务依此执行。
JavaScript的任务分为两种同步和异步
同步任务在主线程上排队执行的任务只有一个任务执行完毕才能执行下一个任务异步任务不进入主线程而是放在任务队列中若有多个异步任务则需要在任务队列中排队等待。
因为JS是单线程在执行代码的时候将所有函数压入执行栈中。同步任务会按照后进先出的原则以此执行。遇到异步任务时将其放入任务队列中。当前执行栈里事件执行完毕后就会从任务队列中取出对应异步任务的回调函数放入执行栈中继续执行。 为什么JS是单线程的脚本语言呢 这是因为JS在执行过程中主要操作为操作DOM树结构如果JS有多个线程的话多线程同时对一个DOM树进行操作浏览器会发生错乱根本无法判断这几个线程的优先级。 执行栈任务队列主线程的区分 执行栈 所有的任务都是在主线程运行形成了执行栈任务队列 是用来存放异步任务的运行结果事件循环是唯一的但任务队列可以有很多个主线程 主线程规定了要执行执行栈中的哪个事件。主线程会不停的从执行栈中读取事件会执行完所有栈中的同步代码这就是主线程循环。当主线程将执行栈中所有的同步任务执行完后主线程将回去查看任务队列是否有任务如果有那些对应的异步任务会结束等待状态进入执行栈并开始执行。 更多关于异步操作Promise的解释请移步另一篇博客
浏览器的事件循环机制
任务队列里边又分宏观任务、微观任务。
宏任务script全部代码、setTimeout、setInterval、setImmediate、I/O、UI渲染微任务Promise.then、Process.nexTick(Node独有)、MutationObserver
new Promise是同步任务Promise.resolve().then()是微任务 当执行栈清空后会先检查任务队列中是否有宏任务如果有就按照先进先出的原则压入执行栈中执行。然后执行该宏任务产生的微任务如果微任务中产生了新的微任务并不会推迟到下一个循环中而是在当前循环中继续执行。 当执行这一轮的微任务完毕后开启下一轮循环执行任务队列中的宏任务。 一次事件循环会处理一个宏任务和所有这次循环中产生的微任务。
对于宏任务和微任务的关系那就是微任务始终跟在当前宏任务的后面当前宏任务还没执行完之前遇到宏任务先扔一边遇到微任务就跟在当前宏任务后面。 这段代码的解释首先JS本身就是一个宏任务所以遇到setTimout时候会将这个宏任务先放到一边继续往下执行遇到了new Promise同步任务所以输出同步宏任务Promise继续往下执行遇到微任务跟在了当前宏任务JS后面随后输出同步宏任务当前宏任务JS执行完毕执行跟在这个宏任务后面的微任务输出同步微任务Promise这个时候当前宏任务带着的微任务全部执行完毕第一个事件循环结束开启第二个事件循环读取第二个宏任务遇到了new Promise同步任务直接输出随后遇到了微任务跟在了当前这个宏任务后面继续向下执行输出异步宏任务当前宏任务执行完毕开始执行跟在后面的微任务输出异步微任务then。