Reader small image

You're reading from  Mastering TypeScript - Fourth Edition

Product typeBook
Published inApr 2021
Reading LevelIntermediate
PublisherPackt
ISBN-139781800564732
Edition4th Edition
Languages
Right arrow
Author (1)
Nathan Rozentals
Nathan Rozentals
author image
Nathan Rozentals

Nathan Rozentals has been writing commercial software for over 30 years, in C, C++, Java and C#. He picked up TypeScript within a week after its initial release in October 2012 and realized how much TypeScript could help when writing JavaScript. He was one of the first people to start blogging about TypeScript, discussing early frameworks such as Backbone, Marionette, ExtJS and AngularJs. He knew he'd hit the mark when Microsoft staff started to reference his blog posts in their CodePlex discussion forums. Nathan's TypeScript solutions now control User Interfaces in IoT devices, run as stand-alone applications for Point-of-Sale solutions, provide complex application configuration web sites, and are used for mission-critical server APIs.
Read more about Nathan Rozentals

Right arrow

Asynchronous Language Features

The JavaScript runtime, whether it is running in the browser, or whether it is running on a server through Node, is single threaded. This means that one, and only one, piece of code will be running at a particular time. This code runs in what is known as the main thread. JavaScript has also been built around an asynchronous approach, meaning that the main thread will not pause when requested to load a resource of some sort. It will, instead, place this request onto an internal queue, which will eventually be processed at a later point in time. While the single-threadedness of JavaScript may take a while to get your head around, it does take away the need for in-memory locking mechanisms, as are used in other languages to handle multiple threads of execution. This makes the JavaScript runtime a little easier to understand, and to work with.

The traditional JavaScript mechanism for dealing with asynchronous requests is through the callback mechanism...

Callbacks

Let's start by examining callbacks, which is the standard mechanism for registering a function to execute after an asynchronous event has occurred. Consider the following example:

function delayedResponseWithCallback(callback: () => void) {
    function executeAfterTimeout() {
        console.log(`5. executeAfterTimeout()`);
        callback();
    }
    console.log(`2. calling setTimeout`)
    setTimeout(executeAfterTimeout, 1000);
    console.log(`3. after calling setTimeout`)
}

Here, we have a function named delayedResponseWithCallback that has a single parameter named callback, which is a function with no arguments that returns void. Within this function, we define another function named executeAfterTimeout, which will log a message to the console, and then execute the callback function that was passed in as the parameter named callback. Note that each console log in this snippet starts with a number, which shows the order of execution of the statements...

Promises

The asynchronous nature of JavaScript does take some time to get used to. Any time we need to wait for a resource, or wait for user input, we need to implement a callback mechanism to handle this correctly. Unfortunately, as a code base grows, we find that we need to rely on callbacks more and more. This can easily lead to what is known as callback hell, where we have so many callbacks that are nested in other callbacks that the code becomes increasingly difficult to read and maintain.

As an example of this, let's consider some code that must read three files one after the other, and print their contents, as follows:

import * as fs from "fs";
fs.readFile("./test1.txt", (err, data) => {
    if (err) {
        console.log(`an error occurred : ${err}`);
    } else {
        console.log(`test1.txt contents : ${data}`);
        fs.readFile("./test2.txt", (err, data) => {
            if (err) {
                console.log(`an error...

Async and await

We have seen that the JavaScript runtime is single threaded and will push any asynchronous calls onto a particular queue within its memory, to be executed later. Using Promises helps us to structure our code to ensure that we only execute a particular section of code once the asynchronous call has completed. We still need to bear in mind, however, that the JavaScript runtime will continue to process our code line by line. This quirk of the language can often lead to weird results, or unwanted errors, if we do not take care when writing code that will be executed asynchronously.

Oftentimes, however, we need to make a series of calls to one asynchronous function after another. In these cases, it would actually be far better if we could pause the execution of our code until the asynchronous code completes. This is what the async and await keywords can do for us. In this section of the chapter, we will explore how to mark functions with the async keyword, in order...

Callbacks versus Promises versus async

As a refresher on the techniques that we have explored in this chapter, let's compare the techniques used when using callbacks, Promises, and async await all in one go. First up, the callback syntax is as follows:

function usingCallbacks() {
    function afterCallbackSuccess() {
        // execute when the callback succeeds
    }
    function afterCallbackFailure() {
        // execute when the callback fails
    }
    // call a function and provide both callbacks
    invokeAsync(afterCallbackSuccess, afterCallbackFailure);
    // code here does not wait for callback to execute
}

Here, we have defined a function named usingCallbacks. Within this function, we have defined two more functions, named afterCallbackSuccess and afterCallbackFailure. We then call an asynchronous function named invokeAsync and pass in these two functions as arguments. One of these functions will be invoked by the asynchronous code, depending on whether the...

Summary

In this chapter, we focused on the asynchronous nature of the JavaScript runtime, and what techniques we can use to work with this feature. We started with callbacks, which is a standard way of handling asynchronous calls within JavaScript. We also explored the concept of callback hell, which is where using callbacks can become a bit of a nightmare. We then explored Promises, showing how the simple but strict syntax can be applied to any type of asynchronous processing. Finally, we examined the new async await syntax that can be used to pause execution of a code block until a Promise has completed.

In the next chapter, we will take a look at decorators, and how we can inject functionality into existing code using a simple decorator convention.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Mastering TypeScript - Fourth Edition
Published in: Apr 2021Publisher: PacktISBN-13: 9781800564732
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $15.99/month. Cancel anytime

Author (1)

author image
Nathan Rozentals

Nathan Rozentals has been writing commercial software for over 30 years, in C, C++, Java and C#. He picked up TypeScript within a week after its initial release in October 2012 and realized how much TypeScript could help when writing JavaScript. He was one of the first people to start blogging about TypeScript, discussing early frameworks such as Backbone, Marionette, ExtJS and AngularJs. He knew he'd hit the mark when Microsoft staff started to reference his blog posts in their CodePlex discussion forums. Nathan's TypeScript solutions now control User Interfaces in IoT devices, run as stand-alone applications for Point-of-Sale solutions, provide complex application configuration web sites, and are used for mission-critical server APIs.
Read more about Nathan Rozentals