Categories


Archives


Recent Posts


Categories


The Practical Problems of Javascript Promises

astorm

Frustrated by Magento? Then you’ll love Commerce Bug, the must have debugging extension for anyone using Magento. Whether you’re just starting out or you’re a seasoned pro, Commerce Bug will save you and your team hours everyday. Grab a copy and start working with Magento instead of against it.

Updated for Magento 2! No Frills Magento Layout is the only Magento front end book you'll ever need. Get your copy today!

Last time we took a look at javascript promises. While promises offer us an async programming experience that’s slightly evolved from continuation passing style APIs they’re not without their own set of tradeoffs.

Today we’re going to look at three distinct aspects of promises in modern javascript that you might find challenging depending on your own background.

Who Promised What?

Problem one is — whose promise library are you going to use? While promises made it into The ECMAScript 2015 standard and (in mid-2019) are built into most modern javascript engines, native promises aren’t the only game in town. Javascript has multiple stand-alone third party promise libraries, and while the open Promise/A+ promise standard gives everyone a base set of functionality, all you need to do is look at their implementation page and weep at the eighty four different javascript libraries that implement some sort of Promise API.

All of a sudden we’re back to the problem of needing to understand an individual author’s idea of how something shoud work. Programmers gonna program, I suppose.

I Make no Promises, I can’t do Golden Rings

The other problem? All those old async libraries aren’t going anywhere. As javascript took off a metric butt ton of libraries adopted continuation passing style async APIs. NodeJS’s filesystem API, many of the popular database libraries, etc. For all that javascript is a fast moving target, for these libraries to change and provide promise-only APIs would be a huge undertaking. There’s also folks who legitimately prefer the continuation passing style APIs and will continue to build and use them.

So, promises may offer your project a slightly better API for dealing with async, but you still need to deal with other people’s code, which means all sorts of async APIs.

Ironically (from the context of this article, as least), one popular solution for the old async APIs comes from one of those promise libraries we were bemoaning earlier.

The Bluebird promise library can promise-ify any function you’d like it to. Well, any function that conforms to node’s de-facto standard of

  1. The async continuation-passing style callback is the last argument to the function
  2. And this callback honors the “argument one is an error, argument two is the success value” convention

If the async API you’re using doesn’t conform to that standard, then you’d need to promisify it on your own, or subject yourself to what “Gary, who doesn’t work here anymore” did to promisify the API.

The First Circle of Hell is Still a Circle of Hell

Promises are often touted as a solution to callback-heck, and while they do reduce the number of nested callbacks you’ll be working with, they don’t remove them entirely. As a client programmer, there’s no way for me to fetch a promise’s value and use it in the current scope.

Put another way, there’s no way for a programmer (with promises alone) to write a simple function that uses a value returned by a promise

const someFunction = function(value) {
    let promise = someApi.somePromiseBasedApi();

    let promiseValue = ??????
    promise.then(function(result){
        // I can access the value here, but there's
        // no way for me to get it up in the main
        // scope and have `someFunction` return its value
    });

    var finalValue = someOtherFunction(promiseValue);
    return finalValue;
}

However, unlike our first two problems, this one has a technical solution. More recent versions of javascript, following the lead of the ECMAScript 2017 Spec, have implemented the async and await keywords. These give javascript the ability to implement “asynchronous functions”, and (from inside asynchronous functions) have a program wait for a promise to resolve and assign its value to a variable

This may, at first, see counterintuitive. Wouldn’t waiting for a promise be the opposite of async? Next time we’ll see how these keywords work, and learn how to read javascript programs using the async/await pattern.

Series Navigation<< Promises: A Better Asynchronous GrammarPromise State >>

Copyright © Alan Storm 1975 – 2019 All Rights Reserved

Originally Posted: 26th July 2019