user3880485
user3880485

Reputation: 51

Wait for asynchronous function to finish before proceeding

I want a variable to be assigned a value which comes from a asynchronous functions callback before it continues to next function/line of code.

In my jsfiddle it's the title variables that I want to get the value of the Soundcloud track API request. Hope you see what I mean, otherwise I'll come back to explain further.

jsfiddle

I recently began understanding how asynchronous functions work, so I understand why my code doesn't really work. What I'm searching for is a way to make variable playerData wait to be run until the titles are assigned.

If that's not possible I'd be grateful for other tips on how to get this to work as I want.

Thanks!

Ps. In my real page every "player" div will contain players with different artists.

Relevant javascript from my jsfiddle where the commented lines is how I would have put it if it wasn't for the async problems:

$(document).ready(function() {
var source = document.getElementById( 'player-template' ).innerHTML;
var playerTemplate = Handlebars.compile( source );

SC.initialize({
  client_id: '90fb9e15c1e26f39b63f57015ab8da0d'
});


var title1;
var title2;

  SC.get("/users/theshins/tracks", function(tracks){
  SC.oEmbed(tracks[0].permalink_url + "/&maxheight=100&maxwidth=300&format=json&sharing=false", document.getElementById('player1'));
      //title1 = tracks[0].title;
  });
  SC.get("/users/theshins/tracks", function(tracks){
  SC.oEmbed(tracks[0].permalink_url + "/&maxheight=100&maxwidth=300&format=json&sharing=false", document.getElementById('player2'));
      //title2 = tracks[0].title;
  });
  SC.get("/users/theshins/tracks", function(tracks){
  SC.oEmbed(tracks[0].permalink_url + "/&maxheight=100&maxwidth=300&format=json&sharing=false", document.getElementById('player3'));
  });
  SC.get("/users/theshins/tracks", function(tracks){
  SC.oEmbed(tracks[0].permalink_url + "/&maxheight=100&maxwidth=300&format=json&sharing=false", document.getElementById('player4'));
  });
  SC.get("/users/theshins/tracks", function(tracks){
  SC.oEmbed(tracks[0].permalink_url + "/&maxheight=100&maxwidth=300&format=json&sharing=false", document.getElementById('player5'));
  });
  SC.get("/users/theshins/tracks", function(tracks){
  SC.oEmbed(tracks[0].permalink_url + "/&maxheight=100&maxwidth=300&format=json&sharing=false", document.getElementById('player6' ));
  });


//Data that will replace the handlebars expressions in our template
var playerData = {
    title1 : title1,
    title2 : title2,
};

$('#player-placeholder').html(playerTemplate(playerData));

});

Upvotes: 0

Views: 420

Answers (2)

Constantinius
Constantinius

Reputation: 35089

With jQuery alone you would chain the promises of each request with the $.when function like so:

var a = $.get("/a");
var b = $.get("/b");
var c = $.get("/c");

$.when(a, b, c).then(function() {
   // render template here
});

I doubt that the soundcloud API returns jQuery promises, but I guess you can wrap the SC.get function to return jQuery promises:

function wrapGet(url) {
    var deferred = $.Deferred();
    SC.get(url, function(result) {
        deferred.resolve(result);
    });
    return deferred.promise();
}

Now you can call it like this:

var a = wrapGet("/users/theshins/tracks").then(function(tracks){
  SC.oEmbed(tracks[0].permalink_url + "/&maxheight=100&maxwidth=300&format=json&sharing=false", document.getElementById('player1'));
      //title1 = tracks[0].title;
  });

var b = ...


$.when(a, b, ...).then(function() {
   // render template here
});

Upvotes: 2

BlaShadow
BlaShadow

Reputation: 11703

If you want to wait until those task being executed I recommend you to use some promise framework like this https://github.com/kriskowal/q

Upvotes: 0

Related Questions