简体   繁体   中英

Node.js event listener blocked?

using the following code I register an node.js event listener waiting for a response from a zeromq connection forwarded through a global nodejs EventEmitter called zmqevent.

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");

Basically the event queue works. The zmq_controller_pub.send emits the request to my external script and the response arrives at node.js emitting an node.js event which fires the event listener defined above.

How can I get the event listener do interrupt the console.log() chain at the end of my script? Current output is like the following:

1
1
1
1
1
1
1
1
event triggered

Basically I want to wait for a response from my zeromq connection for 2 seconds and fire and alternative "offline" result if no response arrives. But not even this simple example is working and the event is fired only at the very end of my script. Do you have an idea? Obviously there must be a silly mistake...

You can't.

JavaScript's concurrency model in NodeJS (and io.js) is that all synchronous code runs before any event handlers that are scheduled on the micro/macrotask queues are drained.

This is just the way the concurrency model works and it's actually quite useful since there are never interrupts that put your code in inconsistent state.

If I understand correctly, you want something like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM