1

So I've been stuck on this for quite a while. I asked a similar question here: How exactly does done() work and how can I loop executions inside done()? but I guess my problem has changed a bit.

So the thing is, I'm loading a lot of streams and it's taking a while to process them all. So to make up for that, I want to at least load the streams that have already been processed onto my webpage, and continue processing stream of tweets at the same time.

loadTweets: function(username) {
    $.ajax({
            url: '/api/1.0/tweetsForUsername.php?username=' + username
        }).done(function (data) {

            var json = jQuery.parseJSON(data);
            var jsonTweets = json['tweets'];

            $.Mustache.load('/mustaches.php', function() {
                for (var i = 0; i < jsonTweets.length; i++) {
                    var tweet = jsonTweets[i];
                    var optional_id = '_user_tweets';
                    $('#all-user-tweets').mustache('tweets_tweet', { tweet: tweet, optional_id: optional_id });

                    configureTweetSentiment(tweet);
                    configureTweetView(tweet);
                }
            });
        });
    }};
}

This is pretty much the structure to my code right now. I guess the problem is the for loop, because nothing will display until the for loop is done. So I have two questions.

  1. How can I get the stream of tweets to display on my website as they're processed?
  2. How can I make sure the Mustache.load() is only executed once while doing this?
Community
  • 1
  • 1
dtgee
  • 1,272
  • 2
  • 15
  • 30

1 Answers1

0

The problem is that the UI manipulation and JS operations all run in the same thread. So to solve this problem you should just use a setTimeout function so that the JS operations are queued at the end of all UI operations. You can also pass a parameter for the timeinterval (around 4 ms) so that browsers with a slower JS engine can also perform smoothly.

       ... 

var i = 0;
var timer = setInterval(function() {

    var tweet = jsonTweets[i++];
    var optional_id = '_user_tweets';
    $('#all-user-tweets').mustache('tweets_tweet', {
        tweet: tweet,
        optional_id: optional_id
    });
    configureTweetSentiment(tweet);
    configureTweetView(tweet);

    if(i === jsonTweets.length){
        clearInterval(timer);
    }
}, 4); //Interval between loading tweets
        ...

NOTE
The solution is based on the following assumptions -

  1. You are manipulating the dom with the configureTweetSentiment and the configureTweetView methods.

    Ideally the solution provided above would not be the best solution. Instead you should create all html elements first in javascript only and at the end append the final html string to a div. You would see a drastic change in performance (Seriously!)

  2. You don't want to use web workers because they are not supported in old browsers. If that's not the case and you are not manipulating the dom with the configure methods then web workers are the way to go for data intensive operations.

tusharmath
  • 10,622
  • 12
  • 56
  • 83