I have a simplified function that looks like this:
function(query) {
myApi.exec('SomeCommand', function(response) {
return response;
});
}
Basically i want it to call myApi.exec
, and return the response that is given in the callback lambda. However, the above code doesn't work and simply returns immediately.
Just for a very hackish attempt, i tried the below which didn't work, but at least you get the idea what i'm trying to achieve:
function(query) {
var r;
myApi.exec('SomeCommand', function(response) {
r = response;
});
while (!r) {}
return r;
}
Basically, what's a good 'node.js/event driven' way of going about this? I want my function to wait until the callback gets called, then return the value that was passed to it.
Since node 4.8.0 you are able to use the feature of ES6 called generator. You may follow this article for deeper concepts. But basically you can use generators and promises to get this job done. I'm using bluebird to promisify and manage the generator.
Your code should be fine like the example below.
If you don't want to use call back then you can Use "Q" module.
For example:
For more information refer this: https://github.com/kriskowal/q
Note: This answer should probably not be used in production code. It's a hack and you should know about the implications.
There is the uvrun module (updated for newer Nodejs versions here) where you can execute a single loop round of the libuv main event loop (which is the Nodejs main loop).
Your code would look like this:
(You might alternative use
uvrun.runNoWait()
. That could avoid some problems with blocking, but takes 100% CPU.)Note that this approach kind of invalidates the whole purpose of Nodejs, i.e. to have everything async and non-blocking. Also, it could increase your callstack depth a lot, so you might end up with stack overflows. If you run such function recursively, you definitely will run into troubles.
See the other answers about how to redesign your code to do it "right".
This solution here is probably only useful when you do testing and esp. want to have synced and serial code.
One way to achieve this is to wrap the API call into a promise and then use
await
to wait for the result.Output:
supposing you have a function:
you can make use of callbacks like this:
To me it worked to use
on the result I expected. This may not be "super general", but in the end "JSON.parse" managed the waiting for the asyncronous call, whilst
result['key']
didn't.