Tag Archives: deferred

Wrap Google map geocoder.geocode in a Promise

Futures and promises are a programming construct to make asynchronous programming easier to apply. They are provided in many JavaScript libraries and frameworks. Below we use Dojo’s implementation to wrap a non-promised based async operation, getting a Geocode from the Google Map API.

The Google geocode service takes a request object (which contains address information) and a callback function that takes a results object and a status string. If status is ok, the results object contains the geocode information (and a lot of other useful information).

In listing one the geoCode function wraps this in a Promise. Inside the function we create a deferred object, then invoke the above async geocode service, then we return the Promise interface of the Deferred object. Note, this is taken from a working application code, and that code works, this below, not tested.

Listing 1.

var geocoder = new google.maps.Geocoder();
 
function geoCode(request) {
    var deferred;
    require([ 'dojo/Deferred' ], function(Deferred) {
        deferred = new Deferred();        
        geocoder.geocode(request, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                deferred.resolve(results);
            } else {
                deferred.reject(status);
            }
        });
        
    });
    
    return deferred.promise;
    
}

You can use this as follows:

var promise = getGeocode(request);

Note that we don’t wait for the async operation to complete, or more correctly, invoke our callback function. The invoker of our geoCode function just gets a Promise object. So?

The Promise object is something that may get a value when it is fulfilled or it may get rejected. You find this out by reacting to those states. How? By using callbacks. So we are right back to where we started, after all the original geocode function also used callbacks. Ah, but here is the difference. With Promises, you are using something with more features and power. The Promise framework allows you to work with async code in a more frameworky way.

One of the nice features of Promises is that they can be “then’able”. “then” functions return a Promise, so they can be chained together: p.then(….).then(….).then(…..); Within each ‘then’, you supply a left and a right callback function, the left is for the resolved, the right is for the rejected state. Example:

var p = getGeocode(request)
p.then(successFunction,failureFunction);

You could also inline everything:

getGeocode(request).then(
    function(results){
       var x = do_something_with_result(results);
       return x;
    },
    function(status){
       do_something_with_status(results);
       throw "failed"
    }
});

These left and right are not chains themselves, there is one chain, but the left or right could be invoked depending on whether the preceding “then” resolved or rejected the promise. Of course, there are more details and each Promise implementation adds their own terminology and features. For example, Dojo has an always function that accepts a callback to invoke no matter what the previous ‘then’ did with the promise.

Apparently moves are afoot to make ‘futures’ part of the core JavaScript standard. These may be following the Promises/A+ specification.

A future blog post will provide a very easy to understand intro to Promises. There doesn’t seem to be a Promise for dummies on the web.

Further reading

YouTube

JavaScript Promises: Thinking Sync in an Async World

Redemption from Callback Hell

Times Developer Network – Promises, Promises

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.