Node.js真的异步完成后台I/O任务吗
Does Node.js really do the background I/O tasks asynchronously?
编辑:我们可以关闭。是不是;难道真的不可能实现异步、无阻塞的javascript吗?
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);
- 将内容复制到文件中
- 执行文件
- 在浏览器中打开一个新选项卡。将url设置为
localhost/1
。还不去 - 在浏览器中打开一个新选项卡。将url设置为
localhost/2
。还不去 - 返回第一个选项卡。按enter键,切换到第二个选项卡后立即按enter键
结果:
控制台日志:
选项卡1:我在
选项卡1:我完成了
选项卡2:我在
选项卡2:我完成选项卡1等待5秒钟以接收结果"1"。
- 标签2也必须等待5秒钟,因为标签1正在睡眠5秒钟
文档中说,除了代码之外,所有内容都是异步的。只有一个线程。一次只有一个请求。请求已入队。
I/O调用应该是异步的,对吧?那么,如果回调来自异步I/O进程,为什么选项卡2必须等待选项卡1呢?
谢谢。
因为sleep
正在阻塞事件循环。
将其替换为setTimemout(function() { /* Code to run */ }, 5000);
,并观察/2
立即做出响应。
实际的I/O是异步的,但您在I/O上执行的所有操作都发生在事件循环中。如果有什么东西阻塞了事件循环,其他一切都必须等待,就像你说的那样。
编辑。为了更清晰,请查看以下ASCII图形:
Event Loop Thread: ------+req1HandlerExistsCall+-------+req1Wait5Sec++++++++++++++++++++++++++req2ExistsCall+-------+req2Immediate+-------------
HTTP I/O: -+req1+--------------------------------------+req2+--------------------------------------+req1Response+--------+req2Response+
File I/O: ----------------------------+exists1+----------------------------------------------------+exists2+---------------------------
基本上,每个线程一次只能有一个。因为第一个请求处理程序会阻塞5秒钟(在速度测试中,用手指基本上不可能击败文件系统),所以直到第一个请求几乎完成后,才开始处理第二个响应。
- 您的代码中没有任何I/O调用
- 你在代码中调用了一个繁忙的睡眠方法,即你的代码需要5秒才能处理。当它正在处理时,其他任何东西都不能在该实例上运行
老实说,这是一个真正的问题,还是您只是想抨击node?
Sleep以阻塞方式实现,并在单线程引擎上运行。
SetTimeout
方法是JavaScript中等待一段时间的等效版本。
还要考虑的是,在JavaScript中,大多数事情都应该涉及resultHandler,因为延续是用函数类型的参数处理的,其他函数将在作业完成时调用。
相关文章:
- WinJS(WP8.1):从后台任务更新辅助磁贴
- 在Meteor.js中运行后台任务
- Meteor中的后台任务
- chrome延长时间,后台任务
- 如何在 AngularJS 中将任务推送到后台
- Node.js真的异步完成后台I/O任务吗
- 无法在JavaScript Windows应用程序中注册到后台任务
- 尝试使用Redis和后台任务更好地理解NodeJS
- 后台任务和正在运行的应用程序检测
- 是否可以通过AJAX调用执行后台PHP服务器任务,该任务不会锁定您的网站
- AngularJS后台任务指令更新控制器
- JavaScript中不干扰UI交互的后台任务
- React-Native:使用推送通知来唤醒后台任务
- Javascript: setInterval用于后台任务的理想块大小
- 使用javascript在后台运行一个任务
- 在PHP后台运行任务,即使在用户退出后
- 如何在应用程序挂起后立即触发Windows 8的后台任务
- 在Angular中打开和关闭后台任务
- 如何在Windows 8 JS Metro应用程序的后台任务中使用时间触发器
- 我怎样才能看到我的基于javascript的UWP是否在“后台任务”中运行?上下文