Function returns a string in place of a promise

3

The code below returns a promise:

function getDealerships(region) {
    return $.ajax({
        method: "GET",
        url: "/api/v1/dealerships?region=" + region
    });
}

So I can wait for the server response and process the result:

var dealerships = getDealerships('sul');
dealerships.done(function(data){
    //...
});

The problem is that I need to implement a simple caching system and thus prevent the server from being queried if the user chooses the same zone:

var dealershipsCache = [];

function getDealerships(region) {
    if ( region in  dealershipsCache )
        return dealershipsCache[region];

    return $.ajax({
        method: "GET",
        url: "/api/v1/dealerships?region=" + region
    });
}

Note that if the region is cached, its value is returned, but what is expected is a promise rather than a string.

How to solve the problem?

    
asked by anonymous 28.06.2016 / 13:37

2 answers

2

You have to create a "false" Promise, ie it gives immediate return if region in dealershipsCache gives true, to getDealerships always give a Promise as a result.

You can do it like this:

var dealershipsCache = [];

function getDealerships(region) {
    return new Promise(function(res, fail) {
        if (region in dealershipsCache) {
            res(dealershipsCache[region]);
        } else {
            $.ajax({
                method: "GET",
                url: "/api/v1/dealerships?region=" + region,
                success: function(response) {
                    res(response);
                }
            });
        }
    });
}

If you need to use technology prior to Promises, and thus support old browsers, you can do so with callbacks:

var dealershipsCache = {};
function getDealerships(region, done) {
    if (region in dealershipsCache) {
        return done(dealershipsCache[region]);
    } else {
        $.ajax({
            method: "GET",
            url: "/api/v1/dealerships?region=" + region,
            success: function(response) {
                done(response);
            }
        });
    }
}

and then flames like this:

getDealerships('brazil', function(res){
    // e aqui podes usar a resposta
});
    
28.06.2016 / 15:44
1

To transform a value into a Promise that was successful, you simply encapsulate the value with Promise.resolve .

var dealershipsCache = [];

function getDealerships(region) {
    if ( region in  dealershipsCache )
        return Promise.resolve(dealershipsCache[region]);

    return $.ajax({
        method: "GET",
        url: "/api/v1/dealerships?region=" + region
    });
}

Solution with jQuery.Deferred :

var dealershipsCache = [];

function getDealerships(region) {
    var defer = null;
    if ( region in  dealershipsCache ) {
        defer = $.Deferred();
        defer.resolve(dealershipsCache[region]);
        return defer.promise();
    }

    return $.ajax({
        method: "GET",
        url: "/api/v1/dealerships?region=" + region
    });
}

Solution with $.fn.promise [NOTE: in some older versions this solution will not work):

var dealershipsCache = [];

function getDealerships(region) {
    if ( region in  dealershipsCache ) {
        return $(dealershipsCache[region]).promise().then(function(elements) {
          return elements[0];
        });
    }

    return $.ajax({
        method: "GET",
        url: "/api/v1/dealerships?region=" + region
    });
}
    
28.06.2016 / 18:17