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 协议 ,转载请注明出处!