I'm dynamically updating a few elements after a setTimeout() function. The jQuery function .text() seems to dynamically update with each change of index of an array while processing. But a bootstrap progressbar which is being changed through .css() and .attr() doesnt seem to dynamically update. Here is my page : http://imdbnator.com/process.php?id=f144caf0843490c0d3674113b03da0c5&redirect=false

You can see that the text gets changed but the progress bar only finishes after the whole setTimeout() function finishes. Also, if I set the delay = 1000. It works. But it slows down by application. Therefore, I need delay = 0. But why doesnt the progressbar change?

Here is my snippet

function launch(a) {
    var inc = 0;
    var maxc = a.length;
    var delay = 0; // delay milliseconds
    var iID = setInterval(function () {    
        var index = inc;
        var movie = a[inc];    
        //start processing function    
        //styling while processing                
        var markerPer = ((index + 1) / rawListNum) * 100; // marker percentage
        $("#procNum").text("(" + (index + 1) + "/" + rawListNum + ")"); //Processing number
        $("#procMovie").text(movie); //Processing Name
        $("div[role='progressbar']").css("width", markerPer + "%").attr("aria-valuenow", markerPer); // progress bar -> DOES NOT WORK    
        if (++inc >= maxc) clearInterval(iID);    
    },
    delay);
}

By way of explanation, a lot of answers are going to point out the fact that most browsers run JavaScript on the UI thread, so they cannot update the interface when JavaScript is being executed. Instead, the browser will wait for the Javascript to finish and return control to the UI thread.

While this is important to keep in mind, it doesn't come into play for your code. If you were updating the progress bar doing something like this:

for (i = 0; i < len; i++) {
    updateProgressBar(i)
};

Then it would definitely prevent the UI from updating until the end.

But you're already doing the right thing by using setTimeout or setInterval, which have asynchronous callbacks into the code. Meaning that the JavaScript is able to pause for long enough to pipe out any UI messages. As evidenced by the fact that the text is able to update dynamically.

As your question asks, why, if the UI is getting updated, is the progress bar not updated as well?

The answer lies in the fact that Bootstrap applies the following CSS to the progress bar:

<!-- language: lang-css -->
.progress-bar {
  -webkit-transition: width .6s ease;
       -o-transition: width .6s ease;
          transition: width .6s ease;
}

When the delay between calls is 0ms, the browser does have time to update the UI, but does not have time to complete the 600ms CSS transition. Consequently, you don't see the animation until the end.

As OhAuth points out, you can prevent the browser from delaying the width update by removing the transition effect with CSS like this:

<!-- language: lang-css -->
.progress .progress-bar {
  -webkit-transition: none;
       -o-transition: none;
          transition: none;
}

If you're looping through a lot of items, the incremental updates will provide some sort of animation. If you wanted to leave on the styling for a generic use case, you could toggle the transitions off and on in your code. As of jQuery 1.8 you can update CSS properties without the vendor prefix, so you'd just need to call .css("transition","none").

Of course, depending on how much work you're doing for each movie, the JavaScript may be able to finish before you can visually detect all of the UI changes, in which case extending the delay wouldn't hurt. If you'd like to test out longer running processes, you can use the following sleep function:

<!-- language: lang-js -->
function sleep(sleepyTime) {
  var start = +new Date;
  while (+new Date - start < sleepyTime){}
}

Here's a demo you can play around where each setting is a variable that you can configure to see how it would react, but the best bet is just to conditionally remove transitions.

Demo in Stack Snippets

<!-- begin snippet: js hide: false --> <!-- language: lang-js -->
var delay, numMovies, throttledMovies, sleepTime, removeTransition;

$("#delay").change(function(){ delay = this.value }).change()
$("#movies").change(function(){ numMovies = this.value }).change()
$("#sleep").change(function(){ sleepTime = this.value }).change()
$("#transition").change(function(){ removeTransition = this.checked }).change()

$("#loadMovies").click(loadMovies);

function loadMovies() {
  var i = 0;
  
  throttledMovies = Movies.slice(0, numMovies)
  
  if (removeTransition) {
    $('#progress-bar-movie').css("transition","none");
  }
  
  var interval = setInterval(function () {
    loadMovie(i)

    if (++i >= numMovies) {
      clearInterval(interval);
      $('#progress-bar-movie').css("transition","width .6s ease");
    }
  }, delay);
};

function loadMovie(i) {
  var movie = throttledMovies[i];
  var percentComplete = ((i + 1) / numMovies) * 100;

  sleep(sleepTime);
  
  // update text
  $("#procNum").text("(" + (i + 1) + "/" + numMovies + ")");
  $("#procMovie").text(movie.Title); 

  // update progress bar
  $('#progress-bar-movie')
    .css('width', percentComplete+'%')
    .attr('aria-valuenow', percentComplete);
};

function sleep(sleepyTime) {
  var start = +new Date;
  while (+new Date - start < sleepyTime){}
}
<!-- language: lang-html -->
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.css" rel="stylesheet"/>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.js"></script>
<script src="http://kylemitofsky.com/libraries/libraries/movies.js"></script>

<!-- params -->
<label for="delay">Delay (ms)</label>
<input type="number" value="0" min=0 max=1000 id="delay"/>
<label for="movies"># Movies </label>
<input type="number" value="250" min=0 max=250 id="movies"/>
<label for="sleep">Sleep time (ms)</label>
<input type="number" value="0" min=0 max=1000 id="sleep"/>
<label for="transition">Remove transition? </label>
<input type="checkbox" checked="true" id="transition"/><br/><br/>

<button class="btn btn-primary btn-lg" id="loadMovies">
  Load Movies
</button><br/><br/>

<p>
  <b>Current Title</b>: <span id="procMovie"></span><br/>
  <b>Progress</b>: <span id="procNum"></span>
</p>

<div class="progress">
  <div class="progress-bar" role="progressbar" id="progress-bar-movie" 
       aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
<!-- end snippet -->