How to "await" for a callback to return?
async/await
is not magic. An async function is a function that can unwrap Promises for you, so you'll need api.on()
to return a Promise for that to work. Something like this:
function apiOn(event) {
return new Promise(resolve => {
api.on(event, response => resolve(response));
});
}
Then
async function test() {
return await apiOn( 'someEvent' ); // await is actually optional here
// you'd return a Promise either way.
}
But that's a lie too, because async functions also return Promises themselves, so you aren't going to actually get the value out of test()
, but rather, a Promise for a value, which you can use like so:
async function whatever() {
// snip
const response = await test();
// use response here
// snip
}
It's annoying that there isn't a straightforward solution, and wrapping return new Promise(...)
is fugly, but I have found an ok work-around using util.promisify
(actually it also kinda does the same wrapping, just looks nicer).
function voidFunction(someArgs, callback) {
api.onActionwhichTakesTime(someMoreArgs, (response_we_need) => {
callback(null, response_we_need);
});
}
The above function does not return anything, yet. We can make it return a Promise
of the response
passed in callback
by doing:
const util = require('util');
const asyncFunction = util.promisify(voidFunction);
Now we can actually await
the callback
.
async function test() {
return await asyncFunction(args);
}
Some rules when using util.promisify
- The
callback
must be the last argument of the function that is gonna bepromisify
- The supposed-callback must be in the form
(err, res) => {...}
Funny thing is we do not need to ever specifically write what's the callback
actually is.