为什么js引擎是单线程的?html
假如js引擎为多线程,DOM操做可能很容易会出现混乱错误的状况:好比某个时刻a线程要操做a节点时,线程b在时刻a以前已将a节点删除了,这时便会出问题。ajax
异步能够避免主线程阻塞,因此对于耗时/不肯定的操做,使用异步是很好的选择。常见的有:处理ajax请求的线程、处理DOM事件的线程、定时器线程、读写文件的线程等。segmentfault
异步线程执行完毕后,会通知主线程执行相应的回调函数,这个通知机制的实现,以下:bash
实际上,主线程只会作一件事情,就是从消息队列里面取消息、执行消息,再取消息、再执行。当消息队列为空时,就会等待直到消息队列变成非空。并且主线程只有在将当前的消息执行完成后,才会去取下一个消息。这种机制就叫作事件循环机制,取一个消息并执行的过程叫作一次循环。数据结构
"任务队列"中的事件,除了IO设备的事件之外,还包括一些用户产生的事件(好比鼠标点击、页面滚动等等)。只要指定过回调函数,这些事件发生时就会进入"任务队列",等待主线程读取。多线程
"任务队列"是一个先进先出的数据结构,排在前面的事件,优先被主线程读取。主线程的读取过程基本上是自动的,只要执行栈一清空,"任务队列"上第一位的事件就自动进入主线程。可是,因为存在"定时器"功能,主线程首先要检查一下执行时间,某些事件只有到了规定的时间,才能返回主线程。异步
while(true) {
var message = queue.get();
execute(message);
}
复制代码
消息队列中的消息具体是什么呢?消息的具体结构是与具体的实现相关的,可是为了简单起见,咱们能够认为:函数
消息就是注册异步任务时添加的回调函数。(多是不对的)
复制代码
从生产者与消费者的角度看,异步过程是这样的:oop
同步能够保证顺序一致,可是容易致使阻塞;异步能够解决阻塞问题,可是会改变顺序性。spa