- Node standard library nodejs的标准库,fs、stream等等
- Node bindlings 是c++与nodejs的沟通桥梁,封装v8和libuv,给上层提供api
- 最后一层是支持nodejs的关键
libuv实现非阻塞
event loop
┌───────────────────────┐
┌─>│ timers │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
│ │ I/O callbacks │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
│ │ idle, prepare │
│ └──────────┬────────────┘ ┌───────────────┐
│ ┌──────────┴────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │
│ └──────────┬────────────┘ │ data, etc. │
│ ┌──────────┴────────────┐ └───────────────┘
│ │ check │
│ └──────────┬────────────┘
│ ┌──────────┴────────────┐
└──┤ close callbacks │
└───────────────────────┘
setTimeout(() => {
const delay = Date.now() - timeoutScheduled;
console.log(`${delay}ms`);
}, 50);
// 异步任务二:文件读取后,有一个 200ms 的回调函数
fs.readFile('./xxx.pdf', (err, data) => {
console.log(err, data);
const startCallback = Date.now();
while (Date.now() - startCallback < 200) {
// 什么也不做
}
});
setImmediate(() => {
console.log('xxx');
});
以上代码执行顺序(个人理解)
timers(跳过)->I/O callbacks(跳过)->poll(队列当前为空)->检查timer
->setTimeOut(肯定没到时间)->回到check->setTImeOut(下一轮循环)->poll(为空,也没有check。添加回调并执行)->setTimeOut(执行或者跳过,主要是看到时间没)->I/Ocallback->setTimeOut()
如果没有setImmediate
timers(跳过)->I/O callbacks(跳过)->poll(为空,也没有check。添加回调并执行)->setTimeOut(肯定没有)->IO->setTimeOut
const fs = require('fs');
setTimeout(() => {
const delay = Date.now() - timeoutScheduled;
console.log(`${delay}ms`);
}, 25);
// 异步任务二:文件读取后,有一个 200ms 的回调函数
fs.readFile('./xxx.js', (err, data) => {
setTimeout(() => console.log(1));
setImmediate(() => console.log(2));
const startCallback = Date.now();
while (Date.now() - startCallback < 200) {
// 什么也不做
}
});
setImmediate(() => {
console.log(xxx);
});
对于上面部分
打印的2,1并且delay time会比225更小,这是多次跳出等待的结果