I just started using async/await and is confused on how it interacts with callback. For example,
fooMethod(function() {
return Promise.resolve("foo");
});
vs
fooMethod(async function() { //add async keyword
return "foo";
});
Must fooMethod be written in a specific way so that it can handle an async function as callback?
if fooMethod is a public library, how do I know that it is safe to add async keyword to the function?
FOLLOW UP
Express router,
app.get('/foo', function (req, res) {
return res.send("foo");
});
app.get('/foo', async function (req, res) {
return res.send("foo");
});
both of these function works, is it safe to use though?
2 Answers 2
Your two callbacks are equivalent. An async function is just syntactic sugar for a regular function that returns a Promise. This means that you can call an async function like a regular function. Here’s a demo:
const foo = async function (arg) {
return arg * 2
}
const bar = function (arg) {
return Promise.resolve().then(() => {
return arg * 2
})
}
const fooReturn = foo(2)
const barReturn = bar(2)
console.log('foo(2) =>', fooReturn.toString())
console.log('bar(2) =>', barReturn.toString())
fooReturn.then(fooResult => console.log('await foo(2) =>', fooResult))
barReturn.then(barResult => console.log('await bar(2) =>', barResult))
However, if the code that takes the callback wants to get a response, you won’t be able to use an async function unless the code is specially designed to check the return value of the callback function and await it if it’s a Promise.
8 Comments
Your two functions are equivalent, but below demonstrates how using await in an async function delays the function execution by an extra tick each time:
function syncTest() {
console.log('sync completed')
return Promise.resolve('foo')
}
async function asyncTest() {
console.log('async completed')
return 'foo'
}
async function awaitTest() {
console.log('await started')
await void 0
console.log('await awaited')
await void 0
console.log('await completed')
return 'foo'
}
console.log('start')
syncTest().then(value => console.log(`sync resolved: ${value}`))
asyncTest().then(value => console.log(`async resolved: ${value}`))
awaitTest().then(value => console.log(`await resolved: ${value}`))
Promise.resolve()
.then(() => console.log('tick 2 completed'))
.then(() => console.log('tick 3 completed'))
.then(() => console.log('tick 4 completed'))
console.log('tick 1 completed')
asyncwhen you don'tawaitfooMethodmust be written in a specific way, it must handle promise returning function. If it doesn't, none of your examples work, if it does then both examples work.Promisesdifferently.cb()then we are safe to add async keyword but if the functtion ends withconst result = cb()then it will not support async keyword unless it resolve the promise from the callback?