个人对浏览器js运行机制的理解
在浏览器中执行 JavaScript 有两个区域,一个是我们平时所说的同步代码执行,是在栈中执行,原则是先进后出,而在执行异步代码的时候分为两个队列,macro-task(宏任务)和 micro-task(微任务),遵循先进先出的原则。
(1)所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
(2)主线程之外,还存在"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
(3)一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
(4)主线程不断重复上面的第三步
过程概要: 调用栈中的同步任务都执行完毕,栈内被清空了,就代表主线程空闲了,这个时候就会去任务队列中按照顺序读取一个任务放入到栈中执行。每次栈内被清空,都会去读取任务队列有没有任务,有就读取执行,一直循环读取-执行的操作
宏任务: script(整体代码), setTimeout, setInterval, setImmediate, I/O, UI rendering
微任务: process.nextTick(Nodejs), Promises, Object.observe, MutationObserver;
微任务浏览器不会刷新 等到这一层的微任务完成 才会一起刷新,批量操作 宏任务 页面完成了 之后会执行,刷新体验效果不好
执行顺序
主线程任务------>微任务------->宏任务
setTimeout(()=>{
console.log("setTimeout1");
Promise.resolve().then(data => {
console.log(222);
});
});
setTimeout(()=>{
console.log("setTimeout2");
});
Promise.resolve().then(data=>{
console.log(111);
});
执行顺序为
111
eventLoop.html:14 setTimeout1
eventLoop.html:16 222
eventLoop.html:20 setTimeout2
网友评论