1

I'm attempting to pull two separate things from outside sources to put onto an HTML page I'm creating. I have a successful AJAX function to pull the most recent video from a particular Youtube channel by parsing through the XML/RSS feed for that channel. I receive this feed through an AJAX call.

I'd also like to get the most recent blog post from a Blogger account. The code for parsing the feed to get the most recent entry shouldn't be difficult, but I'm having trouble with simultaneous AJAX calls. I read somewhere that it can only handle one at a time? I'm weary about queuing them because I don't want to the content on the page to load in steps. I'd rather it all just get fetched simultaneously. How might I go about doing this?

Here is my current script:

<script type="text/javascript" charset="utf-8">
    $(function() {
      $.ajax({
        type: "GET",
        url: "http://gdata.youtube.com/feeds/base/users/devinsupertramp/uploads?orderby=updated&alt=rss&client=ytapi-youtube-rss-redirect&v=2",
        dataType: "xml",
        success: parseXml
      });
    });

    function parseXml(xml) {
        $(xml).find("item:first").each(
            function() {
                var tmp = $(this).find("link:first").text();
                tmp = tmp.replace("http://www.youtube.com/watch?v=", "");
                tmp = tmp.replace("&feature=youtube_gdata", "");
                var tmp2 = "http://www.youtube.com/embed/" + tmp + "?autoplay=1&controls=0&rel=0&showinfo=0&autohide=1";
                var iframe = $("#ytplayer");
                $(iframe).attr('src', tmp2);
            }
        );
    }
</script>
Jon
  • 3,154
  • 13
  • 53
  • 96
  • Your premise (which AFAIK is incorrect, but browser-specific) would pretty much, by definition, disallow anything other than doing it call-by-call, wouldn't it? Another option is making the calls on the server side and aggregating the results, allowing all data to be fetched with a single client call. – Dave Newton May 22 '12 at 03:52
  • What is the blog url? the 2 ones are about feeds? – Oscar Jara May 22 '12 at 03:53
  • @DaveNewton, yes I suppose so. I may end up just doing it server-side. That being said, is a queue how I would do it anyway if I decided against aggregating the results? And Oscar, what are you asking? – Jon May 22 '12 at 03:56
  • Forget about it :-) Mmm, you want to obtain the feed links to put them in the iframe? or what you exactly want to do. – Oscar Jara May 22 '12 at 03:58
  • @OscarJara, the function above pulls the newest video from a Youtube channel and puts it on the page. I need to write another function that will pull the newest blog post from a separate RSS feed, hence the two, separate requests. – Jon May 22 '12 at 04:02

2 Answers2

8

I read somewhere that it can only handle one at a time?

Either you misunderstood what the person was trying to say or they were incorrect. Javascript doesn't run any functions concurrently so someone with poor English might reword that as "can only handle one at a time" but that doesn't mean you can't make multiple AJAX calls. jQuery is smart and will do what it needs to do to make sure both calls are executed eventually.

If you'd like all the content to be loaded simultaneously the sad fact is you can't. However you can make it appear that way to the user by declaring a flag that is set by the success method of each call. Then just keep the content hidden until both flags have been set.

EDIT:

Here's a very simplistic approach to make it appear that they are fetched simultaneously:

<script type="text/javascript" charset="utf-8">
    var youtubComplete = false;
    var otherComplete = false;

    $(function() {
      $.ajax({
        type: "GET",
        url: "http://gdata.youtube.com/feeds/base/users/devinsupertramp/uploads?orderby=updated&alt=rss&client=ytapi-youtube-rss-redirect&v=2",
        dataType: "xml",
        success: parseXml
      });
      $.ajax({
        type: "GET",
        url: "http://someotherdata.com/",
        dataType: "xml",
        success: function() { otherComplete = true; checkFinished(); }
      });
    });

    function parseXml(xml) {
        $(xml).find("item:first").each(
            function() {
                var tmp = $(this).find("link:first").text();
                tmp = tmp.replace("http://www.youtube.com/watch?v=", "");
                tmp = tmp.replace("&feature=youtube_gdata", "");
                var tmp2 = "http://www.youtube.com/embed/" + tmp + "?autoplay=1&controls=0&rel=0&showinfo=0&autohide=1";
                var iframe = $("#ytplayer");
                $(iframe).attr('src', tmp2);
            }
        );
        youtubeComplete = true;
        checkFinished();
    }
    function checkFinished()
    {
        if(!youtubeComplete || !otherComplete) return;
        // ... Unhide your content.
    }
</script>
Spencer Ruport
  • 34,865
  • 12
  • 85
  • 147
  • Good idea. It seemed odd that it wouldn't be able to handle more than one, so thank you for clearing that up. I must be doing something incorrect in my code, then, because my second request isn't working, and it's either overriding the first request or is just incorrect, because the first one isn't giving me any output. – Jon May 22 '12 at 04:05
  • @Jon - I edited my answer. If you are trying to make multiple AJAX requests in a similar manner and it is not performing as expected post that code and either I or someone else will help you figure out what's wrong. :) – Spencer Ruport May 22 '12 at 04:07
  • I figured it out. It was a silly mistake. Thanks for the help! I'll probably use the method you posted - it looks like it should be just what I want. I appreciate it! – Jon May 22 '12 at 04:08
3

The browser will support multiple outbound calls but there is a cap per domain. Take a look at this related Q/A How many concurrent AJAX (XmlHttpRequest) requests are allowed in popular browsers?.

There are several good libraries for doing request scheduling including chaining and parallelizing AJAX calls. One good library is https://github.com/kriskowal/q, which provides async promises framework to enable arbitrarily complicated chaining of AJAX requests. Q minified is about 3.3KB.

// The jQuery.ajax function returns a 'then' able
Q.when($.ajax(url, {dataType: "xml"}))
  .then(function (data) {
     var parsedXML = parseXML(data)
     ...
     // some other ajax call
     var urls = [Q.when($.ajax(url2, {data: {user: data.userId}})),
                 Q.when($.ajax(url3, {data: {user: data.userId}}))];
     // run in parallel
     return Q.all(urls)
  })
  .then(function (data) {
    // data retrieved from url2, url2
  })
Community
  • 1
  • 1