gdutwyg / blog

使用issues记录笔记
0 stars 1 forks source link

Event Loop 几个关键的点 #57

Open gdutwyg opened 5 years ago

gdutwyg commented 5 years ago

数据结构:

堆(queue):基于树抽象数据类型的一种特殊的数据结构,存储引用类型,由系统自动分配存储空间,无序存储,可根据引用直接获取 栈 (stack): 后进先出,存储基本数据类型和对象的指针、方法调用等 队列 (queue): 先进先出

执行栈

当我们调用一个方法的时候,JavaScript 会生成一个与这个方法对应的执行环境,又叫执行上下文(context)。这个执行环境中保存着该方法的私有作用域、上层作用域(作用域链)、方法的参数,以及这个作用域中定义的变量和 this 的指向,而当一系列方法被依次调用的时候。由于 JavaScript 是单线程的,这些方法就会按顺序被排列在一个单独的地方,这个地方就是所谓执行栈。

执行栈是一个类似于函数调用栈的运行容器, 所有同步任务都在主线程上执行,形成一个执行栈 ,当执行栈为空时,JS 引擎便检查事件队列,如果事件队列不为空的话,事件队列便将第一个任务压入执行栈中运行。

事件队列

事件队列是一个存储着 异步任务的回调函数 的队列,当异步任务触发了,就把异步任务的回调函数压入事件队列;

异步任务

总结一下,异步任务分为 宏任务(macrotask)微任务 (microtask)。宏任务会进入一个队列,而微任务会进入到另一个不同的队列,且微任务要优于宏任务执行

宏任务:script(整体代码)、setTimeout、setInterval、I/O、事件、postMessage、 MessageChannel、setImmediate (Node.js) 微任务:Promise.then、 MutaionObserver、process.nextTick (Node.js)

事件循环

JavaScript 有一套机制去处理同步和异步操作,那就是事件循环 (Event Loop)

流程参考下图: image

demo

setTimeout(_ => console.log(4))

new Promise(resolve => {
  resolve()
  console.log(1)
}).then(_ => {
  console.log(3)
})

console.log(2)
// 猜猜打印啥?
// async 是promise的语法糖 类似于promise的处理方式
setTimeout(_ => console.log(4))

async function main() {
  console.log(1)
  await Promise.resolve()
  console.log(3)
}

main()
console.log(2)
// 猜猜打印啥?

参考

最后一次搞懂 Event Loop