【问题标题】:Node.js event listener blocked?Node.js 事件监听器被阻塞?
【发布时间】:2015-04-17 08:13:22
【问题描述】:

使用以下代码,我注册了一个 node.js 事件侦听器,等待来自 zeromq 连接的响应,该连接通过名为 zmqevent 的全局 nodejs EventEmitter 转发。

global.zmqevent.removeAllListeners(req.user._id)
global.zmqevent.on(req.user._id, function (msg, status) {
        console.log('event triggered');
});

global.zmq_controller_pub.send(recipient + " " + String(req.user._id) + " " + "getReportSingle");

console.log("1");
console.log("1");
console.log("1");
console.log("1");
console.log("1");
console.log("1");
console.log("1");
console.log("1");

基本上,事件队列是有效的。 zmq_controller_pub.send 向我的外部脚本发出请求,响应到达 node.js,发出一个 node.js 事件,该事件触发上面定义的事件侦听器。

如何让事件侦听器在脚本末尾中断 console.log() 链? 当前输出如下:

1
1
1
1
1
1
1
1
event triggered

基本上,我想等待来自我的 zeromq 连接的响应 2 秒,如果没有响应到达,则触发和替代“离线”结果。 但即使是这个简单的示例也不起作用,并且仅在脚本的最后触发事件。 你有想法吗?显然肯定是犯了一个愚蠢的错误……

【问题讨论】:

  • 如果要等待 2 秒,请使用 setTimeout(..., 2000)。当响应在该时间段内到达时,使用clearTimeout() 再次取消它。
  • 我不确定你的意思?你能提供一个例子吗?似乎不可能用事件中断 setTimeout()。

标签: javascript node.js events listener blocked


【解决方案1】:

你不能。

NodeJS(和 io.js)中 JavaScript 的并发模型是所有同步代码在微/宏任务队列上调度的任何事件处理程序耗尽之前运行。

这正是并发模型的工作方式,它实际上非常有用,因为从来没有中断会使您的代码处于不一致的状态。

【讨论】:

  • 什么是“等待”外部服务器响应几秒钟而不阻塞所有内容的正确方法,即使响应在几毫秒后到达?我希望某事。比如:function wait(){ if ((gotResponse == false) && (waitingTime
  • @Whezz 根本不会阻止 - 如果你只有那些 console.logs,那真的只有几毫秒。永远不要阻止 i.o 异步执行。如果您需要阻塞 CPU 将代码移到子进程中,您永远不能在 io.js 的主进程上的侦听器(或其他)中执行认真的计算。
【解决方案2】:

如果我理解正确,你想要这样的东西:

var timeout    = null;
var didRespond = false;

// Wait for an event
global.zmqevent.removeAllListeners(req.user._id)
global.zmqevent.on(req.user._id, function (msg, status) {
  console.log('event triggered');

  // Remove the timeout so it won't trigger the handler anymore.
  clearTimeout(timeout);

  // If we already responded (due to the timeout), we don't respond here.
  if (didResponse) { 
    return;
  }

  // Send your response.
  ...
});

// I think the "removeAllListeners"/"on" combo can be folded into one "once":
// global.zmqevent.once(req.user._id, ...)

// Start a timer that triggers in two seconds.
timeout = setTimeout(function() {
  // Do the "offline" handling, since it took more than 2 seconds for the
  // event to arrive.
  didRespond = true;
  ...
}, 2000);

【讨论】:

  • 这正是我想要的!非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-28
  • 1970-01-01
  • 2018-11-01
  • 2020-03-27
  • 1970-01-01
  • 2020-06-24
  • 2018-05-16
相关资源
最近更新 更多