1

考虑一下

只能同时触发一个回调

所以考虑这段代码:

var http = require("http"); 
function onRequest(request, response) {
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  response.end();
}

http.createServer(onRequest).listen(8888);

如果我的应用程序收到请求,则调用 OnRequest。如果一次只能触发一个回调,则请求将排队。这样对吗?

4

1 回答 1

5

Node.js 的设计方式是,当请求到达时,它将信息提供给回调函数并让它处理它,主进程等待下一个请求。

因此,如果您将 onRequest 中的 setTimeout 设置为 10 秒。并向服务器发出 100 个请求,所有请求将在 10 秒后返回您的数据,而不是 10,20,30 ...

由于 node.js 是单进程应用程序,请求将被排队,但人类只需要很少的时间。您可以尝试http://nodejs.org/api/cluster.html等实验性功能来并行处理请求。这里排队并不意味着除非 reques1 得到答复 request2 将不会得到答复,而是意味着节点进程将对它们进行查询,直到每个较早的请求都分配了它们的回调,这根本不会影响您的网站性能。

阅读http://book.mixu.net/node/single.html它也是最棒的书之一 http://www.nodebeginner.org/

编辑 1 Node.js 要求您编写非阻塞代码。在没有阻塞代码的情况下,我们使用回调。

Node.js 是单线程应用程序,但它的行为类似于一个主要的重要线程和其他不太重要的线程池。(没有特定的优先级)。

Eg: An ambulance waits for phone call to come every time. 
    when it gets a call it goes to pick up the patient and take him to the hospital.
    while the doctor is performing operation on the patients. Ambulance team does not 
    switch off their phone and wait for its first patient to get healthy but 
    If they get another call they go to pick up the next guy

    when they were off to receive next guy hospital calls and say first patient is
    healthy and drop him home, ambulance does not leave other guy in pain but complete
    its second task and then drop first guy home.

    so callback was doctorPerformOperation which was put in thread pool
    and
    recieveTheGuy was a blocking operation

因此,从您的代码来看,它非常小,因此每个响应都可能在其请求之后发生,但也有可能在 5 个(几乎)同时请求中,第 3 个请求在第 2 个连接的最后一个“确认”之前分配回调。

更具体的例子

阻塞代码

 setTimeout(function() {
   console.log('bye')
 }, 100);

 while(1) {
 }

'bye' 永远不会被打印出来

无 阻塞代码

 setTimeout(function() {
   console.log('bye')
 }, 100);

 setInterval(function() {
   console.log('hi');
 }, 100);

再见将在 0.1 秒后打印,但如果 hi 在同一实例打印,它可能会延迟一些纳秒。

它在主进程空闲时执行回调。

更多非阻塞

setTimeout(function() {
   console.log('bye')
 }, 100);

 setInterval(function() {
   console.log('hi');
 }, 50);

setInterval(function(){
   console.log('hello');
},100);

猜猜,这会发生什么?

编辑2:

我写了一个小代码

exports.sample = function (res) {
var tcpsocket = net.createConnection(port, host);
tcpsocket.on('connect', function () {
    tcpsocket.write('query');
    console.log('tcp');
});
tcpsocket.on('data', function (data) {
    res.write(data);
});
tcpsocket.on('end', function () {
    console.log('end');
    res.end();
});
tcpsocket.on('error', function (e) {
   var ret={error:'error'}
   res.end(JSON.stringify(ret));
   console.log('Error occured in tcp socket');
       console.log(e);
});
tcpsocket.on('close', function () {
    console.log('socket close');
    res.end();
});
};

现在我连接的套接字是交流套接字,它以 10 秒的间隔写入数据 10 次。所以每个请求大约需要 100 秒才能完成。因为我没有在“数据”事件中调用 res.end,所以浏览器在完整请求完成之前不会加载任何内容。如果您想实时查看数据,您可以使用 curl 获取相同的 url。

结果:当您同时打开 10 个选项卡时,您将能够在 100 秒内看到所有选项卡中的数据(不是 100 秒、200 秒......)

于 2013-09-21T11:07:24.023 回答