I'm looking for a solution to waiting for an event to happen before sending a HTTP response.
Use Case
- The idea is I call a function in one of my routes:
zwave.connect("/dev/ttyACM5");
This function return immediately. - But there exists 2 events that notice about if it succeed or fail to connect the device:
zwave.on('driver ready', function(){...});
zwave.on('driver failed', function(){...});
- In my route, I would like to know if the device succeed or fail to connect before sending the HTTP response.
My "solution"
- When an event happen, I save the event in a database:
zwave.on('driver ready', function(){
//In the database, save the fact the event happened, here it's event "CONNECTED"
});
- In my route, execute the connect function and wait for the event to appear in the database:
router.get('/', function(request, response, next) {
zwave.connect("/dev/ttyACM5");
waitForEvent("CONNECTED", 5, null, function(){
response.redirect(/connected);
});
});
// The function use to wait for the event
waitForEvent: function(eventType, nbCallMax, nbCall, callback){
if(nbCall == null) nbCall = 1;
if(nbCallMax == null) nbCallMax = 1;
// Looking for event to happen (return true if event happened, false otherwise
event = findEventInDataBase(eventType);
if(event){
waitForEvent(eventType, nbCallMax, nbCall, callback);
}else{
setTimeout(waitForEvent(eventType, callback, nbCallMax, (nbCall+1)), 1500);
}
}
I don't think it is a good practice because it iterates calls over the database. So what are your opinions/suggestions about it?
I've gone ahead and added the asynchronous and control-flow tags to your question because at the core of it, that is what you're asking about. (As an aside, if you're not using ES6 you should be able to translate the code below back to ES5.)
TL;DR
There are a lot of ways to handle async control flow in JavaScript (see also: What is the best control flow module for node.js?). You are looking for a structured way to handle it—likely
Promise
s or the Reactive Extensions for JavaScript (a.k.a RxJS).Example using a
Promise
From MDN:
The async computation in your case is the computation of a boolean value describing the success or failure to connect to the device. To do so, you can wrap the call to
connect
in aPromise
object like so:Once you have a
Promise
representing the state of the connection, you can attach functions to its "future" value:You can learn more about Promises on MDN, or by reading one of many other resources on the topic (e.g. You're Missing the Point of Promises).