事件驱动原理

事件驱动原理

简单地说 ,就是由于js代码只在一个线程上运行,他容易被阻塞。例如:复杂的算法运算,js进行复杂的dom操作等等。我们试想下如果一打开页面,就有大量IO请求,都是同步执行的话,页面会有多卡,所以事件驱动最终实际上是解决单线程通道阻塞问题,通过事件队列的方式给主通道让路

浏览器有两个线程,一个是js线程,一个是ui线程 ,两线程是互斥的,一旦一个线程阻塞,另一线程无法响应用户的操作

用户在界面上进行的操作称之为事件(Event)。由用户操作引发的一连串程序的动作,称之为事件驱动(Event-Driver).对事件进行处理程序或函数,我们称之为事件处理程序(Event Handler)
在这里插入图片描述

js虽然是单线程的,但是浏览器是多线程的,GUI渲染线程,js引擎线程,事件触发线程,定时器触发线程,异步请求http线程
当你打开chrome浏览器中的一个tab的时候,有多少线程在为你服务:
1.GUI渲染线程
2.js引擎线程
3.事件触发线程
4.定时器触发线程
5.异步请求http线程

宏任务和微任务

宏任务包括:setTimeout, setInterval, setImmediate, I/O, UI rendering

微任务: promise.then, process.nextTick, quequeMicrotask

为什么要设计宏任务和微任务,比如从客户端发起ajax请求向服务端获取数据,在此过程中,js引擎执行完了主线程上所有代码,在这时,他就要等待异步线程返回结果,为了提高执行效率,充分利用js引擎的资源,会让他去执行微任务,等所有的微任务执行完以后,再回到异步回调返回的结果里面执行相应的逻辑
微任务的性能要高于宏任务,因为微任务是v8引擎自带的api接口,而宏任务是v8引擎对底层定义宏任务api接口的封装
执行优先级:主线程上的任务> 微任务> 宏任务

事件轮询

在这里插入图片描述
js内存中有堆栈,堆中存对象,事件会入栈,如果栈中有异步任务,会将异步任务提交到异步模块进行处理,例如ajax请求,setTimeout,Dom等模块,提交完之后,会回到主线程上,继续执行他未完成的代码和任务,当完成代码和任务,会进入一个事件循环,在循环过程中,会定期去检查任务队列中有没有已完成的任务,任务队列中的任务大多都是由异步模块推送过来的已完成的结果

练习

看完这上面的,可以自己分析一下这些代码的执行顺序

console.log(1)   

setTimeout(()=> {
  console.log(2)
  new Promise(() => {
    console.log(11)
  })
})

queueMicrotask(() => {
  console.log(7)
})

let promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log(10)
  })
  resolve()
  console.log(4)
})

fn()
console.log(3)

promise.then(() => {
  console.log(12)
})

function fn() {
  console.log(6)
}

答案是 1 4 6 3 7 12 2 11 10,你分析对了吗?

猜你喜欢

转载自blog.csdn.net/qq_46299172/article/details/107213712
今日推荐