Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Promisify event handlers and timeout in Nodejs

I have a callback handler to handle a websocket event and I am trying to write a function which would return a promise. The promise should be resolved if the handler is called or rejected if the handler is not executed. Is there a better way to do this?

var callbackCalled = false;
var message = null;

waitForMessage = function() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      if (callbackCalled) {
        callbackCalled = false;
        message = null;
        resolve();
      } else {
        reject();
      }
    }, 5000);
  });
}

onEvent = function(event) {
  console.log("Process the event");
  //set the message
  callbackCalled = true;
};
like image 777
learningtocode Avatar asked Sep 06 '25 17:09

learningtocode


1 Answers

You could use something like this. This will reject is the timeout happens before the incoming event. It will resolve with data if the event happens before the timeout.

function waitForEventWithTimeout(socket, event, t) {
    return new Promise(function(resolve, reject) {
        var timer;

        function listener(data) {
            clearTimeout(timer);
            socket.removeListener(event, listener);
            resolve(data);
        }

        socket.on(event, listener);
        timer = setTimeout(function() {
            socket.removeListener(event, listener);
            reject(new Error("timeout"));
        }, t);
    });
}

You would use it like this:

waitForEventWithTimeout(socket, "myEvent", 1000).then(function(data) {
    // got data here
}, function() {
    // timeout here
});

Note, I add and remove the event listener here to make sure it's not processed too many times or added too many times because event handlers are multi-shot listeners, but promises are one shot.

like image 161
jfriend00 Avatar answered Sep 08 '25 10:09

jfriend00