如何理解js的异步?
js是单线程,这是因为他在浏览器的渲染主线程中运行的,渲染主线程只有一个线程。 渲染主线程承担的很多工作,比如解析html css 页面绘制等... 如果是同步运行js的代码,则会导致主线程的卡死,从而导致页面卡死的状态。 所以浏览器才用异步的方式来避免,具体做法是当某些任务触发时候,比如定时器,网络,事件监听,主线程会交由线程处理,自身立即结束当前任务。当其他线程完成的时候,将实现传递的回调函数包装成任务,加入到消息队列的末尾排队,等待主线程调度的执行。在这样的情况下,就不会造成主线程的阻塞。
任务有优先级吗
任务是没有优先级的,在消息队列中先进先出。
但是消息队列是有优先级的。 根据w3c的最新解释:
- 每个任务都是有任务类型的,同一个任务类型只能在一个队列中,不同的任务类型可以分散在不同的队列中
- 浏览器必须准备好一个微队列,微队列中的任务优先于所有其他任务
tip:随着浏览器的任务类型增加,w3c不再使用宏队列的说法
面试题
阐述下js中的事件循环
事件循环又称为消息循环,是浏览器渲染线程的主要工作方式。
在chrome相关源码中,其实就是通过一个无限循环,不停的从消息队列中取任务进行执行。
就比如说遇到了一个定时器,渲染线程直接交给专门的线程处理,当其他线程处理完之后,在丢入对应的队列中等待执行。
任务是没有优先级的,但是消息队列是有优先级的,这也是为什么微任务优选与任何任务执行,其他队列的任务实际上是由渲染线程决定哪个先执行的。
会存在很多队列,但是必须存在一个微队列。
js中的定时器时间精准吗
- 世界上最准确的是原子钟,cpu里面是没有的
- settimeout 是操作系统层面的,操作系统不同,实现方式不同,也会导致时间是不一致的
- 按照w3c的标准,当settimeout嵌套操作5层了,默认的最小时间是4,这也会带来偏差
- 由于单线程的原因,每个任务执行的时间是不确定的,计时器回调函数只能在主线程空闲的时候去执行。
总结
- 单线程是异步产生的原因
- 事件循环是异步的实现方式