Async / Await Javascript

The purpose of async/await functions are to simplify the behavior of using promises synchronously. Here are my notes on the subject.

1. Async comes in these flavours

1
2
3
4
5
6
const foo = {
async bar() {}
};
async function foo() {};
const foo = async function () {};
const foo = async () => {};

2. Async functions always returns a Promise

The promise is rejected in the case of uncaught exceptions, otherwise it’s resolved to the return value of the async function

1
2
3
4
5
async function foo() {
return 'bar';
}
foo().then(v => console.log(v)); // 'bar'

3. If you await a non promise, things work just fine

1
2
3
4
async function foo() {
return await 'bar';
}
foo().then(v => console.log(v)) // 'bar'

4. When you use the await expression in a function you must make that function async

1
2
3
4
5
6
7
8
9
// do
async function foo() {
await bar()
}
// don't do
function foo() {
await bar();
}

This becomes less obvious in cases like the below

1
2
3
4
// This doens't work
async function foo(items) {
items.forEach(item => bar(await item));
}

This wont work as it is expecting the forEach function to suspend without ever giving it an instruction to do so. You could re write this with Promise.all as shown below.

1
2
3
4
// This does work
async function foo(items) {
await Promise.all(items.map(async item => bar(await item)));
}

5. Use Promise.all to await multiple promises. The alternative will synchronously resolve the promises.

1
2
3
4
5
6
7
// do
await Promise.all([p1, p2, p3])
// don't do (unless you want to work on a return value before making subsequent requests)
await p1;
await p2;
await p3;

6. Async can’t be used with a class constructor.

A constructor should return an instance of its class anyhow. Not a promise.

7. Wait

1
2
const timeout = ms => new Promise(resolve => setTimeout(resolve, ms));
await timeout(100);