Search code examples
javascriptjqueryajaxjsonp.when

JSONP ajax request and jQuery.when()


I have to make a bunch of JSONP calls, and execute some code after they all finish (or fail).

i.e.:

function finished() {
    alert('done!');
}

function method1() {
    return $.ajax('http://example.org/endpoint', {
        data: {
            foo: 'bar'
        },
        dataType: 'jsonp'
    });
}

function method2() {
    return $.ajax('http://example.org/endpoint', {
        data: {
            baz: 'qux'
        },
        dataType: 'jsonp'
    });
}

$.when(method1(), method2()).always(finished);

The only problem is, if any of the requests fail, finished() will not be called.

I can try and detect if one of the ajax calls fails like so:

function method1() {
    var method1_timeout = setTimeout(function() {
        // this call has failed - do something!
    }, 5000);

    var ajax = $.ajax('http://example.org/endpoint', {
        data: {
            foo: 'bar'
        },
        dataType: 'jsonp',
        success: function() {
            clearTimeout(method1_timeout);
        }
    });

    return ajax;
}

But I'm stuck at that point - how do I tell the deferred object that that particular ajax request has failed?

I tried calling the ajax object's error() method:

var method1_timeout = setTimeout(function() {
    ajax.error();
}, 5000);

But no luck.

Any ideas?


Solution

  • I tested your posted code 'as-is' in jsFiddle and it works, even when the JSONP calls fails (of course, requests returns 404 errors because of example.com/endpoint queries).

    So I think I found the answer of your problem in the jQuery documentation, in the $.ajax chapter:

    The server should return valid JavaScript that passes the JSON response into the callback function. $.ajax() will execute the returned JavaScript, calling the JSONP callback function, before passing the JSON object contained in the response to the $.ajax() success handler.

    Check if your JSONP returned JS code are valid and check if you don't have any syntax error in your console that will stop the execution of your JS code on your side (and prevent the always function to be executed).

    EDIT: I reproduced your error. When using jQuery 2.x (edge), it works like intended (try there). Passing to jQuery 1.x (edge), the two methods calls are working but the always func is never called (try there). All my tests have been done under Google Chrome.