有关node.js异步IO调用原理的问题
在Win10中做Node.js实验,看下面的代码:
const fs=require('fs');
fs.writeFile('./file.txt','Hello world!',function(err){
console.log('done.');
});
console.log('finished.');
很多资料称,对于fs这类模块而言,调用fs.writeFile方法时,Nodejs会从线程池中取出一个新的线程,把写文件的操作放在这个新线程中执行。如果这种说法是事实,那么上面的代码(主线程)应当和新线程并行。我希望验证到这一点,于是我故意将主线程拖延数秒,修改代码如下:
const fs=require('fs');
fs.writeFile('./file.txt','Hello world!',function(err){
console.log('done.');
});
console.log('loop begins....');
for(var i=0;i<10000000000;i++){} //会拖延数秒
console.log('finished.');
如果主线程和新线程是并行的,那么写文件的操作应该在主线程陷入for循环的这数秒内快速完成。但结果却出乎意料,在for循环的这段时间里file.txt文件的大小始终是0Byte。直到主线程finished,file.txt中才出现内容。这貌似说明writeFile操作被安排在了当前代码的后面,两者被串行了。我又用readFile做了一次实验,代码如下:
const fs=require('fs');
fs.readFile('./test.iso',function(err,data){
console.log('done.');
});
console.log('loop begins....');
for(var i=0;i<10000000000;i++){} //会拖延数秒
console.log('finished.');
其中,file.iso是我随便找来的一个文件,大小将近700MB。运行程序后,我观察资源监视器。的确是先单独执行for循环,主线程finish后才开始向内存提交数据,仍然是把操作串行起来。不过,通过观察资源监视器可以验证一个事实,fs的确开启了新线程。
我又转移到Linux中做同样的实验,结论与上面一致。
这个现象令我十分费解,恳请指点:fs开启的新线程(异步IO操作)为什么不能和主线程并行?是我运行node时遗漏了什么参数吗?还是我没有理解哪个重要概念?如果这些操作必须串行起来,那么开启新线程的意义是什么呢?谢谢。