编辑:我们可以关闭。 Isn't truly asynchronous, non-blocking javascript impossible?
var PATH = require ("path");
var URL = require ("url");
var sleep = function (ms){
var start = new Date ().getTime ();
while ((new Date ().getTime () - start) < ms);
}
require ("http").createServer (function (req, res){
if (URL.parse (req.url).pathname === "/1"){
console.log ("tab 1: I'm in");
PATH.exists ("test", function (exists){
sleep (5000);
res.writeHead (200, {"Content-Type": "text/plain"});
res.end ("1");
console.log ("tab 1: I'm done");
});
}else{
console.log ("tab 2: I'm in");
res.writeHead (200, {"Content-Type": "text/plain"});
res.end ("2");
console.log ("tab 2: I'm done");
}
}).listen (80);
localhost/1
。不要走了。localhost/2
。不要走了。结果:
控制台日志:
标签1:我在 表1:我已经完成了 表2:我在 表2:我已经完成了
选项卡1等待5秒钟以接收结果“1”。
文档说除了代码之外所有都是异步的。只有一个线程。一次只能有一个请求。请求已入队。
I / O调用应该是异步的,对吧?那么,如果回调来自异步I / O进程,为什么选项卡2必须等待选项卡1?
感谢。
答案 0 :(得分:5)
因为您的sleep
阻止了事件循环。
将其替换为setTimemout(function() { /* Code to run */ }, 5000);
并观看/2
立即回复。
实际的I / O是异步的,但是您在I / O上执行的所有操作都发生在事件循环中。如果某事阻止事件循环,其他一切都必须等待,就像你说的那样。
EDIT。为了更加清晰,请查看以下ASCII图形:
Event Loop Thread: ------+req1HandlerExistsCall+-------+req1Wait5Sec++++++++++++++++++++++++++req2ExistsCall+-------+req2Immediate+-------------
HTTP I/O: -+req1+--------------------------------------+req2+--------------------------------------+req1Response+--------+req2Response+
File I/O: ----------------------------+exists1+----------------------------------------------------+exists2+---------------------------
基本上,每个线程一次只能有一个。因为第一个请求处理程序会阻塞5秒钟(并且在速度测试中用手指敲打文件系统基本上是不可能的),所以第二个响应甚至在第一个请求几乎完成之后才开始处理。
答案 1 :(得分:2)
老实说,这是一个真正的问题还是你只想尝试bash节点?
答案 2 :(得分:1)
Sleep以阻塞方式实现,并在单线程的引擎上运行。
SetTimeout
方法是在JavaScript中等待一段时间的等效版本。
还要考虑一下,在JavaScript中,大多数事情都应该涉及一个resultHandler,因为在完成作业时,函数类型参数会处理为要调用的其他函数。