Skip to content

Instantly share code, notes, and snippets.

@domenic
Last active June 24, 2021 16:37
Show Gist options
  • Save domenic/1604916 to your computer and use it in GitHub Desktop.
Save domenic/1604916 to your computer and use it in GitHub Desktop.
Using promises in a UI context

The scenario:

  • We are writing a digital textbook-reading app.
  • You get two copies of each digital textbooks: "basic" or "enhanced." Only one computer can have the enhanced copy.
  • You can only print from the enhanced copy.

The problem statement:

  • We want a simple printAsync() method that we can attach to our click handler.

The complications:

  • If the user has the basic version, we need to check if it's possible for them to upgrade to enhanced:
    • If so, ask the user if they want to upgrade, and then continue the print operation.
    • If not, error out: printing is impossible.
  • Printing is an asynchronous operation, that could fail (e.g. if the printer is out of paper).
  • Due to some horrible threaded C++ code, we get deadlocks if the user navigates through the book at the same time as the book is printing, so we need to block the UI while it prints.
@petkaantonov
Copy link

I think it will look better for promises if it is kept flat like:

// Returns a promise that will be fulfilled if and only if the book becomes (or already is) an
// enhanced copy.
function ensureEnhancedAsync(book) {
    if (!book.isEnhanced) {
        // Return an already-fulfilled promise (with no fulfillment value): we're good to go.
        return Q();
    } 
    // First see if we could possibly upgrade.
    return drm.getCouldUpgradeAsync().then(function (couldUpgrade) {
        // Now act on that knowledge: either give up if we can't, or upgrade if we can.
        if( !couldUpgrade ){
            // This will bubble up, resulting in the promise returned from ensureEnhancedAsync
            // being rejected.
            throw new Error("You cannot print from the basic version, and have already downloaded "
                          + "the enhanced version on another computer. Use that computer instead.");             
        }
        // Ask the user if they want to upgrade.
        return dialogs.confirmAsync("Do you want to upgrade to enhanced?")
    }).then( function( result ) {
        // If they do, perform the upgrade.
        if( result ) {
            return drm.upgradeAsync(book);
        }
        else {
            throw new Error("Since you have not chosen to upgrade, printing is not available.");
        }
    });

}

This should work the same if I'm not mistaken. Right now it almost looks like no callback hell was solved after all as the code keeps growing on the right...

Copy link

ghost commented Jun 23, 2015

Awesome demonstration of the power of promises!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment