There’s a special syntax to work with promises in a more comfortable fashion, called “async/await”. It’s surprisingly easy to understand and use.
Async functions
Let’s start with the
async
keyword. It can be placed before a function, like this:async
function
f
(
)
{
return
1
;
}
The word “async” before a function means one simple thing: a function always returns a promise. If the code has
return <non-promise>
in it, then JavaScript automatically wraps it into a resolved promise with that value.
For instance, the code above returns a resolved promise with the result of
1
, let’s test it:async
function
f
(
)
{
return
1
;
}
f
(
)
.
then
(
alert)
;
// 1
…We could explicitly return a promise, that would be the same:
async
function
f
(
)
{
return
Promise.
resolve
(
1
)
;
}
f
(
)
.
then
(
alert)
;
// 1
So,
async
ensures that the function returns a promise, and wraps non-promises in it. Simple enough, right? But not only that. There’s another keyword, await
, that works only inside async
functions, and it’s pretty cool.Await
The syntax:
// works only inside async functions
let
value =
await
promise;
The keyword
await
makes JavaScript wait until that promise settles and returns its result.
Here’s example with a promise that resolves in 1 second:
async
function
f
(
)
{
let
promise=
new
Promise
(
(
resolve,
reject)
=>
{
setTimeout
(
(
)
=>
resolve
(
"done!"
)
,
1000
)
}
)
;
let
result=
await
promise;
// wait till the promise resolves (*)
alert
(
result)
;
// "done!"
}
f
(
)
;
The function execution “pauses” at the line
(*)
and resumes when the promise settles, with result
becoming its result. So the code above shows “done!” in one second.
Let’s emphasize:
await
literally makes JavaScript wait until the promise settles, and then go on with the result. That doesn’t cost any CPU resources, because the engine can do other jobs meanwhile: execute other scripts, handle events etc.
It’s just a more elegant syntax of getting the promise result than
promise.then
, easier to read and write.
Can’t use
await
in regular functions
If we try to use
await
in non-async function, that would be a syntax error:
function
f
(
)
{
let
promise=
Promise.
resolve
(
1
)
;
let
result=
await
promise;
// Syntax error
}
We can get such error in case if we forget to put
async
before a function. As said, await
only works inside async function
.Summary
The
async
keyword before a function has two effects:- Makes it always return a promise.
- Allows to use
await
in it.
The
await
keyword before a promise makes JavaScript wait until that promise settles, and then:- If it’s an error, the exception is generated, same as if
throw error
were called at that very place. - Otherwise, it returns the result, so we can assign it to a value.
Together they provide a great framework to write asynchronous code that is easy both to read and write.
With
async/await
we rarely need to write promise.then/catch
, but we still shouldn’t forget that they are based on promises, because sometimes (e.g. in the outermost scope) we have to use these methods. Also Promise.all
is a nice thing to wait for many tasks simultaneously.
No comments:
Post a Comment