前端常见面试题: 浏览器的执行机制

80 阅读2分钟

浏览器的事件环,同步,异步, 如何执行的? 问题1:进程和线程的区别? 进程: 计算机是以进程来分配任务和调度任务的 (进程间通信 ipc) 线程: 进程中包含线程 举例: 浏览器是多个进程组成的 每个页签(tag)都是独立的进程 浏览器中主要的进程有:主进程 网络进程 绘图进程插件 一个页签都是一个进程 渲染进程里面有: 渲染线程(UI线程: 负责页面渲染,布局,绘制) JS线程: JS引擎解析代码 UI线程和JS线程是互斥的 JS也是单线程的,主线程是单线程,代码是从上到下执行,也就是同步代码,定时器,请求,用户的事件操作都是异步的(每开一个定时器,都会生成一个新的线程) 异步任务的划分,常见的有两种宏任务和微任务,微任务主要有Promise.then(ECMAScript提供的),mutationObserver(Html5提供的),queueMiccrotask 宏任务主要有默认的script代码段,ui渲染也是一个宏任务 setTimeout,请求,用户的事件,messageChannel,setImmediate,requestFrameAnimation(这个是放在渲染的) 代码的执行过程中,有两个队列宏任务队列(消息队列,底层是由多个队列组成,我们实际看的话宏任务队列当成一个来理解),时间到了后会将任务放到宏任务队列中 webApi,代码执行过程中,宏任务和微任务分别有自己的队列,微任务优先于宏任务,宏任务每次执行一个,微任务每次执行一堆,这就是EventLoop事件循环机制(事件环)

Promise.resolve().then(() => {
  console.log('ok1')
  Promise.resolve().then(() => {
    console.log('ok2')
    Promise.resolve().then(() => {
      console.log('ok3')
    })
  })
})
setTimeout(() => {
  console.log('timeout1')
}, 500)
setTimeout(() => {
  console.log('timeout2')
}, 500)

依次打印ok1 ok2 ok3 timeout1 timeout2 渲染是要在特定的时机才能渲染,根据浏览器的刷新频率,不是每一轮都要渲染的(一定在微任务之后)

 document.body.style.background = 'red'
    console.log(1)
    Promise.resolve().then(() => {
      console.log(2)
      document.body.style.background = 'yellow' // 如何让页面强制重绘
    })
    console.log(3)

上面代码的执行过程是什么? 1,3,2,黄色,那么,红色不执行吗,记住一句话,渲染都是在微任务之后,会合并 看代码

<button id="button">123</button>
  <script>
     button.addEventListener('click',()=>{
       console.log('listener1');
       Promise.resolve().then(()=>console.log('micro task1'))
    })
    button.addEventListener('click',()=>{
       console.log('listener2');
       Promise.resolve().then(()=>console.log('micro task2'))
    })
    button.click(); // click1() click2()
  </script>

用户点击会产生两个宏任务,两个宏任务会依次执行,如果是直接调用会在同一轮执行! 在看来一个例子

Promise.resolve().then(() => {
    console.log('Promise1')
    setTimeout(() => {
        console.log('setTimeout2')
    }, 0);
})
setTimeout(() => {
    console.log('setTimeout1');
    Promise.resolve().then(() => {
        console.log('Promise2')
    })
}, 0);
</script>

常用面试题

console.log(1);
async function async () {
    console.log(2);
    await console.log(3); 类似于 Promise.resolve(console.log(3)).then(() => console.log(4))
    console.log(4)
}
setTimeout(() => {
  console.log(5);
}, 0);
const promise = new Promise((resolve, reject) => {
    console.log(6);
    resolve(7)
})
promise.then(res => {
  console.log(res)
})
async (); 
console.log(8);