j3ssi3ftw j3ssi3ftw - 3 months ago 16
Javascript Question

Making async jquery calls

$(document).ready(function(){

$.getJSON("https://api.deckbrew.com/mtg/sets", function(sets) {
$(sets).each(function() {
$('<div id="' + this.name + '" class="set"/>')
.text(this.name)
.appendTo("#collection");

});
});

$.getJSON("https://api.deckbrew.com/mtg/cards", function(cards) {
$(cards).each(function(){
$('<div id="' + this.name + '" class="card"/>')
.text(this.name)
.appendTo("#" + this.editions[0].set);

});
});

});


I was wondering how I might (without using ajax and sticking to the "getJSON" method) make the two calls happen asynchronously. I can't make anything useful happen with the second jQuery object; I believe that's because of the synchronous nature of the calls. How can I make them work in order?

Answer

If you want these to happen in order, then you need to specifically serialize them and using the built-in promises that getJSON() returns is a simple way to do that:

$(document).ready(function () {
    $.getJSON("https://api.deckbrew.com/mtg/sets").then(function (sets) {
        $(sets).each(function () {
            $('<div id="' + this.name + '" class="set"/>')
                .text(this.name)
                .appendTo("#collection");
        });
    }).then(function () {
        $.getJSON("https://api.deckbrew.com/mtg/cards").then(function (cards) {
            $(cards).each(function () {
                $('<div id="' + this.name + '" class="card"/>')
                    .text(this.name)
                    .appendTo("#" + this.editions[0].set);
            });
        });
    });
});

Or, a little faster (end to end time) would be to launch both requests at the same time and then process the results in order. Again using jQuery promises to manage this:

$(document).ready(function(){
    $.when(
        $.getJSON("https://api.deckbrew.com/mtg/sets"), 
        $.getJSON("https://api.deckbrew.com/mtg/cards")
    ).then(function(r1, r2) {
        // process sets
        var sets = r1[0];
        $(sets).each(function() {
          $('<div id="' + this.name + '" class="set"/>')
          .text(this.name)
          .appendTo("#collection");
        });

        // process cards
        var cards = r2[0];
        $(cards).each(function(){
          $('<div id="' + this.name + '" class="card"/>')
          .text(this.name)
          .appendTo("#" + this.editions[0].set);
        });
    });
});

This last scheme uses $.when() to tell us when both ajax calls are done and it also sequences the results for us, regardless of which one actually finished first.

Comments