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:
asyncfunctionf(){letpromise=newPromise((resolve,reject)=>{setTimeout(()=>resolve("done!"),1000)});letresult=awaitpromise;// wait till the promise resolves (*)alert(result);// "done!"}f();
The function execution “pauses” at the line
(*) and resumes when the promise settles, with resultbecoming 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:functionf(){letpromise=Promise.resolve(1);letresult=awaitpromise;// 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
awaitin 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 errorwere 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