The code written in Javascript is executed in synchronous way while, nowadays, the more and more asynchronous functions needed to be used.
Therefore, it is important to be familiar with the evolution of asynchronous behaviors and solutions provided by Javascript: callbacks, promise, async-await.
const firstCall = () => {
return fetch('someUrl',(response)=> {
let firstRes = response.json()
let secondRes = firstRes.id
return fetch(`otherUrl/${secondRes}`, (response)=> {
let thirdRes = response.userName
return fetch(`someOtherUrl/${thirdRes}`), (response => {
let fourthRes = response.phoneNumber
return fetch(`getUserbill/${fourthRes}`, (response)=> {
let fifthRes = response.billAmount
return fifthRes
})
})
})
})
}
firstCall()
Using callbacks is really bad pattern with coding since it makes hard to not only track down the execution-flow, even for the developer who actually wrote it but also debug.
As using Promise, it is really easy to track the code flow down, thankfully, but still the style with the Promise pattern doesn't looks like a synchronous flow a bit and throws some complexity compare to javascript functions we wrote.
It is because of all the callback functions returned by the Promise in order to keep chaining responses and handling asynchronous execution.
And now this is the newsest asynchronous solution or pattern brought by ES8, async - await.
This new pattern will have developers to write code about asynchronous execution in a style how synchronous execution fucntion written in.
the declaration of async
defines an asynchronous function which returns an AsyncFunction object, which is the instance of the Async Function constructor, allows to use more efficiently and enables asynchronous, promise-based behavior
when an async
function is called, it returns Promise with either resolved status when a function returns a value, or rejected status when a function throws an exception or some value
another keyword await
, provided by async
, will pause the execution of the function declared with async
when Promise has been passed into, the execution resumed and returns the resolved value
Example Code below
// standard promise pattern
let getData =() => {
return fetch('someUrl')
.then(response => console.log(response))
.catch(error => console.log(error.message))
}
//async-await pattern
let getData = async() => {
let responseFromServer = ""
try {
responseFromServer = await fetch('someUrl')
console.log(responseFromServer)
}
catch(error) {
responseFromServer = error
console.log(responseFromServer.message)
}
}
Look how the code style in async-await is pretty much looks like the pattern of function executed syncrhonously, and the readability has been improved.
async function can have zero or as many await
expression as needed
await
expression will pause or suspend the execution through out the entire async function, yielding control of execution and subsequently resuming progress only when an awaited promise-based operation is either fulfilled or rejected.
as Promise is always be returned value by async function, a resolved value of the Promise will be considered as a returned by the expression with await
aysnc/await pattern, which is just a good-looking syntax of handling asynchronous execution, behaves similar to combination of generators and promises
as Async Function always returns a promise, a returned value without wrapped by promise will be wrapped by promise implicitly
easier to understand that the body of Async Function is divided by await
expression; if there is none, it means there is no division
the very Top-level-code, up to and including the first await
expression, runs synchronously; if there is none of await
expression meaning that the function will execute in synchronously
if there is any await
expression written, the execution of Async Function will be ended up asynchronously
the execution of Async Function will be suspended or losing control when the execution meets the first await
expression configured with the pending Promise status
later when first await
returns either resolve or rejected Promise, Async Function will re-gain the control over the execution until the progress meets the next await
expression