要理解这个问题,我们先思考一个麦当劳的服务员的例子。
我们去了麦当劳,向服务员点一份薯条。这时,服务员并不是立刻把薯条给我们,只是给厨房送入你的点单。然后我们在一旁等待。
这时服务员又开始接受下一位顾客的点单。同样的,服务员并不会立刻把食物送出,他只是给厨房送入你点的单而已。
5分钟后,我们的薯条炸好了。厨房师傅把薯条放在窗口,同时打一声铃。听到铃声后,服务员就把我们的薯条交给我们了。
NodeJS其实也是这样的运行逻辑。所以从整个系统的角度看,NodeJS不是单线程。但是从你的代码看,NodeJS是单线程,因为你的代码
就是那个服务员,你同时只能做一件事情。但幸运的是,你不需要亲自去做,你只需要向另一个叫EVENT LOOP的线程发出你的请求,EVENT LOOP
又会开启系统中的线程,去做实际的工作。当工作完成时,EVENT LOOP线程向你返回结果。你再做相应的处理。
所以,对于NodeJS,有这样的一句话:
everything runs in parallel except your code
写段代码来验证一下吧:
'use strict';
var fs = require('fs');
fs.mkdir('./test',function(err,data){
if(err)
return console.log('err ' + err);
console.log('success ' + data);
});
while(true){
console.log('infinity loop');
}
看一下这段代码,思考:
1. test文件夹会被创建吗?
2. success或者err信息会被控制台输出吗?
我们一步步分析。首先代码向EVENT LOOP线程发出一个请求,要它创建test文件夹。当TEST文件夹创建成功后,代码输出success信息。当代码运行到这里时,创建文件夹的请求已经被发出了。所以文件夹会被创建。
然后代码进入while循环,并一直停留在这里。
当EVENT LOOP创建完文件夹并把这个信息返回时,代码并不能处理这个信息,因为代码会一直留在while循环里面。所以success信息不会被打印。
以上,就是NodeJS虽然是单线程,但却可以快速响应请求的原因了。