节点回调同时触发

时间:2013-09-21 10:59:25

标签: javascript node.js

考虑this

  

同时只能有一个回调攻击

请考虑以下代码:

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。 如果一次只能触发一个回叫,那么请求就会排队。是不是?

1 个答案:

答案 0 :(得分:5)

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

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

由于node.js是单进程应用程序,因此请求将排队,但人类只需很短的时间。您可以尝试使用http://nodejs.org/api/cluster.html等实验性功能来并行处理请求。这里的排队并不意味着除非来自requested1,否则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个连接的最后'ack'之前分配回调。

更具体的例子

阻止代码

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

 while(1) {
 }
永远不会打印

'再见'

无阻止代码

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

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

再见将在.1秒后打印,但如果喜欢在同一个实例打印,它可以延迟几纳秒。

当主进程空闲时执行回调。

更多非阻止

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();
});
};

现在我连接的套接字是一个c套接字,它以10秒的间隔写入数据10次。因此每个请求大约需要100秒才能完成。因为我没有在'data'事件中调用res.end,所以浏览器不会加载任何内容,直到完整请求完成。如果您想要实时查看数据,可以使用curl作为相同的网址。

结果:当您同时打开10个标签时,您将能够在100秒(而不是100秒,200秒......)中查看所有标签中的数据