【浏览器的页面循环系统】

--------------------- 浏览器的页面循环系统 ----------------

一、事件的循环系统

1、要想在线程运行过程中,能够接受并执行新的任务,就需要采用事件循环机制

2、如何设计好一个线程模型,能让其能够接受其他线程发送的消息呢?

①一个通用的模式是 - 消息队列 --主线程从消息队列中取任务,其他线程给消息队列塞任务

3、处理其他进程发送过来的任务

渲染进程专门有一个IO线程用来接收其他进程传进来的消息--接收消息之后,会将这些消息组装成任务-发送给渲染主线程

4、安全退出主线程
每次执行完一个任务后,会判断是否有设置退出标志

5、总结:

①对于已经确定好的任务,可以使用一个单线程来按照顺序处理这些任务

②若在线程执行过程中接收并处理新的任务,就需要引入循环语句和事件系统

③如果要接收其他线程发送过来的任务,需要引入消息队列

④如果其他进程要想发送任务给页面主线程,那么先通过IPC把任务发送给渲染进程的IO线程,IO线程再把任务发送给 页面主线程

⑤消息队列机制并不是太灵活,为了适应效率和实时性,引入了微任务

每个宏认为都有一个微任务表,对于临时安排的任务放入微任务表,当宏任务完成后,继续执行微任务

总之,浏览器页面是由消息队列 和事件循环系统来驱动的

消息队列和主线程循环机制保证了页面有条不紊的运行

二、setTimeout是怎么实现的


它就是一个定时器,用来指定某个函数在多少毫秒之后执行

1、为了支持定时器的实现,浏览器增加了延时队列

当执行完当前任务后,去执行到期的延迟任务(eg:SetTimeout任务)
2、其次,由于消息队列排队和一些系统级别的限制,通过setTimeout设置的
回调任务并非总是可以实时地被执行

①当前任务很耗时
②嵌套调用时,系统会设置最短时间间隔为4s(超过5层)
③未激活的页面,setTimeOut最小间隔为1000ms
④setTimeOut设置回调函数的this是指window,可以使用箭头函数解决
⑤延时执行做大值为2147483647,溢出会导致定时器立即执行


三、XMLHttpRequest

1、把一个函数作为参数传递给另外一个函数,那作为参数的这个函数就是回调函数

2、同步回调:callback是在主函数返回之前执行的

3、回调函数在主函数 外部执行的过程称为异步回调 ,有两种方式

①把异步函数 做成一个任务,添加到消息队列尾部
②把异步函数添加到微任务队列中,这样就可以在当前任务的末尾处执行微任务了

XMLHttpRequest(获取服务器数据,局部更新页面) 发起请求,是由浏览器的其他进程或者线程去执行,然后再将执行的结果利用IPC的方式通知渲染进程,之后渲染进程再将对应的消息添加到消息队列中。


四、宏任务与微任务

产生微任务的两种方式 :

① 使用MutationObserver 监控某个DOM节点,然后再通过JavaScript 来修改这个节点,或者为这个节点添加、删除部分子节点,当DOM节点发生变化时,就会产生DOM变化记录的微任务

②使用Promise, 当调用Promise.resolve()或者Promise.reject()的时候,也会产生微任务


五、Promise

1、解决的问题 -- 异步编码风格的问题

 

 


六、async/ await 使同步的方式去写异步代码

1、因为Promise的编程模型充斥着大量的then方法,虽然解决了嵌套回调问题,
但是在语义 方面仍然存在缺陷,这就是async/await 出现的原因

2、使用async/ await可以实现用同步代码的风格来编写异步代码,这是因为saync/await的基础基础使用了生成器和Promise, 生成器是协程的实现,利用生成器可以实现生成器函数的暂停和恢复

 

 

 

 

 

 

 

猜你喜欢

转载自www.cnblogs.com/QQ-lala/p/12573587.html
今日推荐