-1

I have a for block that iterates a list of objects. Each object's name will be displayed in a div (#console).

When the code runs, console.log is output-ed in real time. However, it seems that the method that is supposed to append data to #console executes only after when the for block completes.

How do I make doSomething() run in real time as well?

for(var i = 0; i < objectList.length; i++)
{
    console.log(objectList[i]); //  this runs immediately
    doSomething(objectList[i]); //  this runs only AFTER the loop completes
}

function doSomething(obj)
{
    $("#console").append(obj.name);
    // other stuff
}
Liaoo
  • 425
  • 6
  • 21
  • 1
    its working, see an example here : https://jsfiddle.net/e6c4h8qd/ it's just console.log and its working expectedly. Can you frame your question in a working demo on jsFiddle or Codepen ? – Abhishek Kumar Aug 02 '18 at 04:01
  • Possible duplicate of [JavaScript closure inside loops – simple practical example](https://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Obsidian Age Aug 02 '18 at 04:04
  • `this runs only AFTER the loop completes` - not so - the issue is page render timing – Jaromanda X Aug 02 '18 at 04:04
  • @ObsidianAge not likely relevant at all – Jaromanda X Aug 02 '18 at 04:04
  • Jaramonda X is right, the jsfiddle from Abhishek Kumar has removed the jQuery that appends to the DOM, so it's removed the problem. – Brett Aug 02 '18 at 04:05
  • Shouldn't the render of a DOM update be a blocking function? Is jQuery doing something smart to delay/batch all the DOM manipulation? – Brett Aug 02 '18 at 04:06
  • I've added a `debug;` after `$("#console").append(obj.name);` and you can see it stops after the first loop and both outputs are there - https://codepen.io/anon/pen/rrdgWO – ibex Aug 02 '18 at 04:08
  • https://www.youtube.com/watch?v=cCOL7MC4Pl0 – melpomene Aug 02 '18 at 04:09
  • Possible duplicate of https://stackoverflow.com/questions/19058858/jquery-append-in-loop-dom-does-not-update-until-the-end – Steve Aug 02 '18 at 04:29

1 Answers1

1

Your code blocks the DOM from rendering until it finishes executing, which is why you see #console rendering only after the loop completes.

You could use setTimeout to let the DOM render, and do something like this:

var objectList = [{name: 'hello'}, {name: 'world'}];

function loopThroughList() {
  var i = 0;
  var loop = function () {
     if (i >= objectList.length) {
       return;
     }
     console.log(objectList[i]);
     doSomething(objectList[i]);
     setTimeout(loop, 0);
     i++;
  };
  loop();
}

function doSomething(obj) {
     $("#console").append(obj.name);
}

loopThroughList();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="console"></div>

Note that this is a pretty slow loop, since setTimeout tends to actually timeout for 4ms+ per iteration.

Also see: jQuery append in loop - DOM does not update until the end

Steve
  • 10,435
  • 15
  • 21