Find out how to return the result of an asynchronous function, promise based or callback based, using JavaScript
Say you have this problem: you are making an asynchronous call, and you need the result of that call to be returned from the original function.
Like this:
const mainFunction = () => {
const result = asynchronousFunction()
return result
}
but asynchronousFunction()
performs some asynchronous call in it (for example a fetch()
call), and can’t directly return the result value. Perhaps internally it has a promise it needs to wait for, or a callback. Like this:
const asynchronousFunction = () => {
return fetch('./file.json').then(response => {
return response
})
}
What can you do instead?
Async/await is the most straightforward solution. You use the await
keyword instead than a promise-based approach, like the one we used before:
const asynchronousFunction = async () => {
const response = await fetch('./file.json')
return response
}
In this case in mainFunction
we need to add async to the function signature, and await before we call asynchronousFunction()
:
const mainFunction = async () => {
const result = await asynchronousFunction()
return result
}
Now this returns a promise, because it’s an async function:
mainFunction() //returns a Promise
So to get the result back you can wrap this in an IIFE like this:
(async () => {
console.log(await mainFunction())
})()
The code looks like synchronous code you are used to from other languages, but it’s completely async.
Another approach is to use callbacks. But while with async/await we could change just the asynchronousFunction()
code, in this case we have to
- modify the
asynchronousFunction()
code - modify the
mainFunction()
code - modify the calling code, too
Here’s an example. asynchronousFunction()
receives a new function as a parameter, which we call callback
. It invokes it passing the response
object:
const asynchronousFunction = callback => {
return fetch('./file.json').then(response => {
callback(response)
})
}
This function is passed by mainFunction
:
const mainFunction = () => {
const callback = result => {
console.log(result)
}
asynchronousFunction(callback)
}
The final piece of the puzzle is in the function that calls mainFunction
. Since we can’t return the response straight from mainFunction
, because we get that asynchronously, the calling function must change how it processes it.
So instead of const result = mainFunction()
, we could use
const callbackFunction = result => {
console.log(result)
}
const mainFunction = callback => {
asynchronousFunction(callback)
}
//call the code
mainFunction(callbackFunction)