Creating asynchronous code with promises and async/await

We often need to write code that behaves in an asynchronous fashion. By this, we mean that we need to start a task off and leave it running in the background while we do something else. An example of this could be when we have made a call out to a web service, which may take a while to return. For a long time, the standard way in JavaScript was to use a callback. A big problem with this approach is that the more callbacks we need, the more complex and potentially error-prone our code becomes. This is where promises come in.

A promise tells us that something will happen asynchronously; after the asynchronous operation finishes, we have the option to continue processing and work with the result of the promise, or to catch any exceptions that have been thrown by the exception.

Here's a sample that demonstrates this in action:

function ExpensiveWebCall(time : number) : Promise<void> {
return new Promise((resolve, reject) => setTimeout(resolve, time));
}
class MyWebService {
CallExpensiveWebOperation() : void {
ExpensiveWebCall(4000).then(()=> console.log(`Finished web
service`))
.catch(()=> console.log(`Expensive web call failure`));
}
}

When we write a promise, we optionally take in two parameters—a resolve function and a reject function that can be called to trigger the error handling. Promises supply two functions for us to cope with these values, so then() will be triggered by successfully completing the operation and a separate catch function that copes with the reject function.

Now, we are going to run this code to see its effect:

console.log(`calling service`);
new MyWebService().CallExpensiveWebOperation();
console.log(`Processing continues until the web service returns`);

When we run this code, we get the following output:

calling service
Processing continues until the web service returns
Finished web service

Between the Processing continues until the web service returns and Finished web service lines, there is a four-second delay that we would expect because the application is waiting for the promise to return before it writes out the text in the then() function. What this is demonstrating to us is that the code is behaving asynchronously here because it is not waiting for the web service call to come back when it executed the processing console log.

We might be tempted to think that this code is a bit too verbose, and that scattering Promise<void> is not the most intuitive way for others to understand that our code is asynchronous. TypeScript provides a syntactic equivalent that makes it much more apparent where our code is asynchronous. With the use of the async and await keywords, we easily turn our previous sample into something much more elegant:

function ExpensiveWebCall(time : number) {
return new Promise((resolve, reject) => setTimeout(resolve, time));
}
class MyWebService {
async CallExpensiveWebOperation() {
await ExpensiveWebCall(4000);
console.log(`Finished web service`);
}
}

The async keyword tells us that our function is returning Promise. It also tells the compiler that we want to process the function differently. Where we find await inside an async function, the application will pause that function at that point until the operation that is being awaited returns. At that point, processing continues, mimicking the behavior we saw inside the then() function from Promise.

In order to catch errors in async/await, we really should wrap the code inside the function in a try...catch block. Where the error was explicitly caught by the catch() function, async/await does not have an equivalent way of handling errors, so it is up to us to deal with problems:

class MyWebService {
async CallExpensiveWebOperation() {
try {
await ExpensiveWebCall(4000);
console.log(`Finished web service`);
} catch (error) {
console.log(`Caught ${error}`);
}
}
}
Whichever approach you choose to take is going to be a personal choice. The use of async/await just means it wraps the Promise approach so the runtime behavior of the different techniques is exactly the same. What I do recommend though is, once you decide on an approach in an application, be consistent. Don't mix styles as that will make it much harder for anyone reviewing your application.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.68.14