Event Loop 事件循环

事件

事件是可以被Javascript侦测到的行为,通俗的讲就是当用户与Web页面进行某些交互时,解释器就会创建响应的event对象以描述事件信息。

JavaScript 是一门 单线程 语言,即同一时间只能执行一个任务,即代码执行是同步并且阻塞的。

任务队列 (task queue)

队列 是一种 FIFO(First In, First Out) 的数据结构,它的特点就是 先进先出。

栈 (Stack)

栈 是一种 LIFO(Last In, First Out)的数据结构,特点即 后进先出。

调用栈 (Call Stack)

js的事件执行栈就是先进后出,最底层是全局,从上到下读取js,遇到事件就会将其推入栈顶,执行完毕后再推出栈。

由于js单线程同步执行,当我们需要发起了一个网络请求,或者设置了一个定时器延时,就会需要一个异步的队列来储存。因此,就会有宏任务(队列)和微任务(队列)。

宏任务和微任务

宏任务

每次执行栈执行的代码就是一个宏任务(包括每次从事件队列中获取一个事件回调并放到执行栈中执行)。浏览器为了能够使得JS内部(macro)task与DOM任务能够有序的执行,会在一个宏任务执行结束后,在下一个宏任务执行开始前,对页面进行重新渲染。

宏任务包含:

  • script(整体代码)
  • setTimeout
  • setInterval
  • I/O
  • UI交互事件
  • postMessage
  • MessageChannel
  • setImmediate(Node.js 环境)

微任务

在当前 task 执行结束后立即执行的任务。也就是说,在当前task任务后,下一个task之前,在渲染之前。所以它的响应速度相比宏任务会更快,因为无需等待渲染。也就是说,在某一个macrotask执行完后,就会将在它执行期间产生的所有microtask都执行完毕(在渲染前)。

微任务包含:

  • Promise.then
  • Object.observe
  • MutationObserver
  • process.nextTick(Node.js 环境)

暂存

后面有些深入的概念还没想好怎么写,大概是事件与动画相互之间的影响之类的,所以这篇文章先暂时写到这。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!