nodejs(libuv)事件循环在移至下一阶段或以循环方式运行之前是否在一个阶段(队列)中执行所有回调?

问题描述 投票:2回答:1

我正在研究libuv在Node中提供的事件循环。我遇到了following blog by Deepal Jayasekara,并且在YouTube上也看到了Bert Belder和Daniel Khan的解释。

有一点我不清楚,根据我的理解,事件循环在进入一个阶段之前先处理一个阶段的所有项目。因此,在这种情况下,如果setTimeout阶段不断向其添加回调,则应该能够阻止事件循环。

但是,当我尝试复制它时-不会发生。以下是代码:

var http = require('http');

http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.write('Hello World!');
  console.log("Response sent");
  res.end();
}).listen(8081);


setInterval(() => {
  console.log("Entering for loop");
// Long running loop that allows more callbacks to get added to the setTimeout phase before this callback's processing completes
 for (let i = 0; i < 7777777777; i++); 
 console.log("Exiting for loop");
}, 0);

事件循环似乎以循环方式运行。它首先执行在我向服务器发送请求之前添加的回调,然后处理该请求,然后继续进行回调。感觉好像正在运行一个队列。从我所了解的一点来看,没有一个队列,所有到期的计时器回调都应先执行,然后再进入下一阶段。因此,以上代码段不应返回Hello World响应。

对此可能的解释是什么?谢谢。

javascript node.js event-loop
1个回答
2
投票

如果查看libuv本身,则会发现事件循环中运行计时器的可操作部分是函数uv_run_timers()

uv_run_timers()

它的工作方式是事件循环在当前时间设置一个时间标记,然后在不更新循环时间的情况下,一个接一个地处理所有在该时间到期的计时器。因此,这将触发所有已经超过其时间的计时器,但不会在处理已到期的计时器时触发任何即将到期的新计时器。

这会导致调度更加公平,因为它运行所有到期的计时器,然后运行并运行事件循环中其余类型的事件,然后返回以再执行其他到期的计时器。这将不会处理任何不在此事件循环周期开始时到期的定时器,而是在处理其他定时器时到期的定时器。因此,您会看到所询问的行为。

上述函数从事件循环的void uv__run_timers(uv_loop_t* loop) { struct heap_node* heap_node; uv_timer_t* handle; for (;;) { heap_node = heap_min(timer_heap(loop)); if (heap_node == NULL) break; handle = container_of(heap_node, uv_timer_t, heap_node); if (handle->timeout > loop->time) break; uv_timer_stop(handle); uv_timer_again(handle); handle->timer_cb(handle); } } 中使用以下代码调用:

main part

请注意在呼叫int uv_run(uv_loop_t *loop, uv_run_mode mode) { DWORD timeout; int r; int ran_pending; r = uv__loop_alive(loop); if (!r) uv_update_time(loop); while (r != 0 && loop->stop_flag == 0) { uv_update_time(loop); uv__run_timers(loop); ran_pending = uv_process_reqs(loop); uv_idle_invoke(loop); uv_prepare_invoke(loop); .... more code here } 之前立即呼叫uv_update_time(loop)。设置uv__run_timers()引用的计时器。这是uv__run_timers()the code

uv_update_time()
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.