0

Imagine there is a Dashboard with some Items on the page. When page loads, e would like to handle it like this:

  1. Load and render the Dashboard.
  2. Use async call (dojo.Deferred + setTimeout) to load all Items.
  3. Add Items to the Dashboard.

Once an Item has been loaded, we add it to the Dashboard. During this async load we want the page to be available for interaction (UI-thread is not frozen).

The code should probably look like this:

var deferred = new Deffered();

setTimeout(function() {
  array.forEach(items, function(item, i) {
    loadItem();

    deferred.progress(i + ' - loaded');
  });
  deferred.resolve();
}, 0)

deferred.then(function() {
  addItemsToDashboard();  
}, function(err) {
}, function(progress) {
  console.debug('Update:', progress);
});

However this doesn't work as expected. The page got frozen for the whole duration of Items to load.

Any suggestion what is wrong or how to handle this?

0leg
  • 13,464
  • 16
  • 70
  • 94
  • 1
    If your `array.forEach(...)` construction blocks, then forcing its execution into a new thread with `setTimeout()` will only help unblock the current (onload or document.ready) thread. When executed in the thread instantiated by `setTimeout()`, it will block there instead, a few moments later, and that's more than likely what you have observed. Involving a Deferred (in the way you have tried) won't help either. If anything, it makes matters slightly worse by giving the processor even more to do. However, there's still hope - it all hangs on the nature of `loadItem()`, which we need to see. – Roamer-1888 Oct 16 '15 at 13:57
  • This looks like basically a more elaborate duplicate of http://stackoverflow.com/questions/33145579/dojo-using-settimeout-to-load-widgets-in-async-way but ultimately with the same problem, which ultimately boiled down to us not knowing what widget is being instantiated that is bottlenecking that long (which is presumably what's going on in `loadItem`). Also, as I explained there, there is only one UI thread in JavaScript. `setTimeout` has nothing to do with multithreading; it simply waits for the next turn of execution. – Ken Franqueiro Oct 16 '15 at 23:11

1 Answers1

0

The solution was to use setTimeout along with recursive function, like this:

var counter = 0;

recursiveFunc: function(element) {
  setTimeout(function() {
    // Do stuff for element[counter]

    if (++counter < numberOfElements) {
      recursiveFunc(element);
    }
  }, 0);
}

recursiveFunc(element[counter])

The UI thread would still be buggy, but at least it is not frozen. This solution was picked as a fast one. For a long-one it was decided to optimize the code to get rid of sync XHR request.

0leg
  • 13,464
  • 16
  • 70
  • 94