node.js如何实际使用事件循环?

时间:2014-08-16 00:34:08

标签: javascript node.js

我测试代码

///create the web server
http.createServer(app).listen(app.get('port'), function(){
  console.log('Express server listening on port ' + app.get('port'));
});
///
function compute() {
var x = 1111111112;
    while (x > 0) x--;//about 6 seconds
   setImmediate(compute);//then do it again
}
compute();

假设我们有一个任务compute(),它需要几乎连续运行,并进行一些CPU密集型计算。如果我们还想处理其他事件,比如在同一个Node进程中提供HTTP请求,我发现无法使用process.nextTick()调整JS线程上的CPU时间,因为process.nextTick的事件循环中的oberver是空闲的观察者。 列出了观察员优先级:

  1. idle observer //process.nextTick具有最高优先级
  2. I / O观察者//第二个是I / O观察者包括Web请求和其他I / O操作
  3. 检查观察者// setImmediate()函数'观察者是检查观察者
  4. 所以我使用setImmediate将整个计算切割成多个工作,以便其他Observer(空闲和I / O)可以在Javascript继续运行compute()函数之前处理它们的事件,就像请求一样。

    结果很奇怪: 当请求到来时,它会被处理但不会同时处理。因为我将compute()的计算时间设置为大约6秒,为什么我的浏览器无法获得结果直到这么多秒过(大于6秒) 所以我开始将计算时间减少到大约50毫秒,这比以前小得多。

    ///create the web server
    http.createServer(app).listen(app.get('port'), function(){
      console.log('Express server listening on port ' + app.get('port'));
    });
    ///
    function compute() {
    var x = 11111112;//I decrease this number for reducing the running time of compute(); 
        while (x > 0) x--;//about 50 ms
       setImmediate(compute);//then do it again
    }
    compute();
    

    然后一切都很快。

    我担心的是:在整个操作中,请求应该在6秒后处理,以及为什么它会持续很长时间? 我一直认为正在运行的模型如下:

    1. 计算6秒
    2. 如果事件循环发现I / O观察者(Web请求)正在等待,请将请求和响应处理到客户端浏览器

    3. 然后事件循环继续像compute()

    4. 那样完成他的工作
    5. 再次循环
    6. 但似乎node.js将请求操作切成了很多部分,导致请求处理这么长时间?

      我错了吗?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

这是节点js的基本概念。 Node js是基于事件的。为什么这个这么重要?因为它说明了Node如何实现异步并具有无阻塞的I / O。

每当Task启动时,它都会进入事件循环队列,然后节点js解释器将请求发送到事件循环,事件循环检查任务是I / O阻塞还是非I / O阻塞。如果其I / O阻止请求,则事件循环将其发送到由节点js库(libuv)管理的线程池。线程池管理诸如网络,数据库操作,文件系统和其他.event循环之类的任务,因此总是在主线程上运行,因为节点js是单个线程。所有的I / O操作都在线程池上运行。当任务在线程轮询中完成时,它将调用回调并再次传递到队列中,主线程从队列中拉出请求并进行处理。