关于使用回调作为 Node 和 http 类的控制流模式的菜鸟问题。根据我对事件循环的理解,所有代码都是阻塞的,i/o 是非阻塞的并使用回调,这是一个简单的 http 服务器和一个伪 rest 函数:
// Require
var http = require("http");
// Class
function REST() {};
// Methods
REST.prototype.resolve = function(request,response,callback) {
// Pseudo rest function
function callREST(request, callback) {
if (request.url == '/test/slow') {
setTimeout(function(){callback('time is 30 seconds')},30000);
} else if (request.url == '/test/foo') {
callback('bar');
}
}
// Call pseudo rest
callREST(request, callback);
}
// Class
function HTTPServer() {};
// Methods
HTTPServer.prototype.start = function() {
http.createServer(function (request, response) {
// Listeners
request.resume();
request.on("end", function () {
// Execute only in not a favicon request
var faviconCheck = request.url.indexOf("favicon");
if (faviconCheck < 0) {
//Print
console.log('incoming validated HTTP request: ' + request.url);
//Instantiate and execute on new REST object
var rest = new REST();
rest.resolve(request,response,function(responseMsg) {
var contentType = {'Content-Type': 'text/plain'};
response.writeHead(200, contentType); // Write response header
response.end(responseMsg); // Send response and end
console.log(request.url + ' response sent and ended');
});
} else {
response.end();
}
});
}).listen(8080);
// Print to console
console.log('HTTPServer running on 8080. PID is ' + process.pid);
}
// Process
// Create http server instance
var httpServer = new HTTPServer();
// Start
httpServer.start();
如果我打开浏览器并在一个选项卡中使用“/test/slow”然后在另一个选项卡中使用“/test/foo”访问服务器,我会得到以下行为 - “foo”立即响应“Bar”然后迟到 30 秒,“慢”响应为“时间为 30 秒”。这正是我所期待的。
但是如果我在浏览器中打开 3 个选项卡并在每个选项卡中连续使用“/test/slow”访问服务器,“慢”正在被处理并串行/同步响应,以便 3 个响应以 30 秒的间隔出现.如果它们是异步处理的,我期待响应会紧接着发生。
我做错了什么?
谢谢你的想法。
最佳答案
这其实不是服务器的错。您的浏览器正在打开一个连接并在请求之间重新使用它,但是一个请求在前一个完成之前无法开始。您可以通过几种方式看到这一点:
- 查看 Chrome 开发工具的网络选项卡 - 最长的条目将显示请求处于
阻塞
状态,直到前两个完成。 - 尝试在不同的浏览器(或在正常和隐身窗口中各打开一个)中打开速度较慢的页面 - 这会阻止共享连接。
因此,只有当同一个浏览器窗口向同一个服务器发出多个请求时才会发生这种情况。另请注意,XHR (AJAX) 请求将打开单独的连接,因此它们可以并行执行。在现实世界中,这不会成为问题。
关于javascript - Node.js - 为什么我的一些回调没有异步执行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22162693/