事件循环 && 并发模型
Q: 事件机制是怎样的?
Q: 怎样的事件是可以阻塞后续代码继续运行的?
Q: 回调函数在逻辑上是怎么实现代码异步执行的?
JavaScript运行时
Q: JS运行时指的是什么? A: JS引擎 + 附加API.
Node.js即是JS运行时, 包含有V8引擎, 并提供系列服务器端API.
浏览器也是JS运行时, 包含有对应的JS引擎, 并提供Web API(DOM, XMLHTTPRequest, Timer等).
JS引擎提供以下这些语义概念的优化实现, 其中就包含有
- 栈
- 函数调用 形成栈帧. 每个函数创建一个调用帧.
- 帧包含参数和局部变量. this值. arguments值在这时确定指向.
- 外层函数被调用即被压入栈, 内层函数接着被调用继续压入栈
- 调用完成, 函数先入后出, 出栈
- 堆
- 非结构化内存区域
- 分配JS对象
- 队列
- 待处理消息 形成队列
- 每个消息都存在与之关联的函数
事件循环时, 而JS运行时从消息队列的先进入队列消息开始处理, 这个消息被移出队列,并作为输入参数调用与之有关的函数. 函数调用即会创造新的栈帧.
事件循环
while (queue.waitForMessage()) {
queue.processNextMessage();
}
事件循环阶段
graph TD
incoming:data,etc.外部输入数据-->轮询阶段(poll)
轮询阶段(poll)-->检查阶段(check)
检查阶段(check)-->关闭事件回调阶段(close callbacks)
关闭事件回调阶段(close callbacks)-->定时器检测阶段(timer)
定时器检测阶段(timer)-->I/O事件回调阶段(I/O callbacks)
I/O事件回调阶段(I/O callbacks)-->闲置阶段(idle, prepare)
闲置阶段(idle, prepare)-->轮询阶段(poll)
- 执行完成
- 队列pop出的单个消息完全被执行完之后才会处理其它消息.
- 添加消息
- 零延迟