Node.js TypeScript Async Await
Learn how to use Async / Await with strict TypeScript typings
For quite a while now I’ve been using Async / Await in place of Promises. There are tons of advantages and I’m not going to go into great detail here as there are hoards of people, far more qualified than I to explain why. Here’s Mostafa talking on the topic over at HackerNoon.
Traditional Promises
We can break the usage of Async / Await down individually. To begin with, lets look at creating a promise and how it’s called.
public static doThisThing(val: number): Promise<boolean> {
}
If you’re using TypeScript (which I hope you are!). You’ll notice that we actually get a compile error. ” A function whose declared type is neither ‘void’ nor ‘any’ must return a value.”
To fix this we can return a new promise and then subsequently call it.
public static doThisThing(val: number): Promise<boolean> {
return new Promise((resolve: (result: boolean) => void, reject: (result: boolean) => void) => {
if(val === 1) {
resolve(true);
} else {
resolve(false);
}
});
}
this.doThisThing(1)
.then((result: boolean) => {
})
It’s fairly simple, though it can be a bit of a chore if you’re typing it correctly. By this I mean declaring the promise resolve and reject functions and parameters.
Using Async
Now we can make the function much easier to write, without changing our calling function. By adding an async operator in front of the function name, we are instructing the compiler to wrap this function inside a promise and return it.
public static async doThisThing(val: number): Promise<boolean> {
if (val === 1) {
return true;
} else {
return false;
}
}
this.doThisThing(1)
.then((result: boolean) => {
})
Using Await
Now if you’re in a position where you have multiple async functions, you may want to wrap all of them inside a Promise.all, or you could use the await operator.
Note, you can only do this if you’re within a function as you also must add the async operator in the function which calls your returning function.
public static async doThisThing(val: number): Promise<boolean> {
if (val === 1) {
return true;
} else {
return false;
}
}
public static async x() {
const result: boolean = await this.doThisThing(1);
}
Handling Errors
A quick mention on error handling. As we’re no longer assigning a resolve function to the promise prototype, we are able to use normal try catch methodology of handling errors. This wouldn’t usually work due to the fact that try catch doesn’t catch anonymous callbacks.
public static async doThisThing(val: number): Promise<boolean> {
if (val === 1) {
return true;
} else {
return false;
}
}
public static async x() {
try {
const result: boolean = await this.doThisThing(1);
} catch (error) {
throw new Error(error);
}
}
Note, we can’t type the catch error into a specific type due to different browsers and engines returning different error types.
I would like to get into more detail about this topic at a later date. If you would like to see more information about this, please let me know in the comments below.