Home Blog CV Projects Patterns Notes Book Colophon Search

Promises

Promises can be used instead of callbacks. The main advantage is that they are easier to compose.

Here's how we write the Callback example with Promises:

getUser("token").then((person) => {
    if (!person) {
        return Promise.reject("Bad response from getUser API");
    }
    // Do something with firstName and lastName
    console.log(person.firstName, person.lastName);
}).catch((err) => {
    return Promise.reject(err);
});

Where getUser is an asynchronous Promise API call that is passed a token. The callback specified in then() is for the result, the callback specified in catch() is for any errors.

An implementation might look like this:

function getUser(token) {
    return new Promise((resolve, reject) => {
        if (token.length === 0) {
            reject(new Error("Invalid token"));
        } else {
            resolve({firstName: "james", lastName: "gardner"});
        }
    });
};

Notice again that the API implementation doesn't throw an error, it calls the resolve callback with the error as the first argument.

Notice also that resolve() will only pass one argument, so we need to put the data into an object and extract it in the calling code.

So far this doesn't seem to have added much improvement, but the key advantage is that you can use the result of the getUser() call multiple times, whether it has resolved or not. The promise will just call your code as soon as it can.

Here's an example:

const person = getUser("token")

person.then((person) => {
    if (person.firstName === "james") {
        console.log("First name is james");
    }
});

person.then((person) => {
    if (person.lastName === "gardner") {
        console.log("Last name is gardner");
    }
});

This is especially useful when you are dealing with complex dependencies between things, because you can write the code for the next part of the puzzle, separate from the code the handles the result.

You can turn node.js callback-based async functions in promise-based ones using denodify.

If you are using TypeScript, you can add Promise type definitions by putting a suitably adjusted line similar to this at the top of the file:

/// <reference path="../../node_modules/typescript/lib/lib.es6.d.ts" />

Promise returning functions can be written:

function getUser(token): Promise<any> {
    ...
};

Copyright James Gardner 1996-2020 All Rights Reserved. Admin.