6

I recently found the following question online:

Write a function that takes an object and appends it to the DOM, making it so that events are buffered until the next tick? Explain why this is useful?

Here is my response:

function appendElement(element) {
    setTimeout(function() {
        document.body.appendChild(element);
    }, 0);
}

Why did I set the interval to zero?

According to this article, setting the timeout to 0, delays the events until the next tick:

The execution of func goes to the Event queue on the nearest timer tick. Note, that’s not immediately. No actions are performed until the next tick.

Here's what I am uncertain of:

  • Is my solution correct?
  • I cannot answer why this approach is beneficial

For reference, I got this question from this website listing 8 JavaScript interview questions.

I'd also like to point out that I am asking this question for my own research and improvement and not as part of a code challenge, interview question, or homework assignment.

Sam
  • 7,252
  • 16
  • 46
  • 65
Levi Hackwith
  • 9,232
  • 18
  • 64
  • 115
  • This will allow you to see each item being added, one at a time (very quickly of course). If you just put it in a loop, the browser will wait until it's finished before repainting the screen. This is an example of synchronicity. – Ian May 15 '13 at 02:58
  • Just for clarification, you're talking about the function being called inside of a loop, yes? Also, such an approach would cause multiple repaints, correct? – Levi Hackwith May 15 '13 at 03:00
  • I'm sorry, I don't know why I assumed this code was being called in a loop. I re-read just now. I guess my point was that if your function was being called in a loop (say from 0 to 9), you would/could see each element being appended, because there's a repaint since they're asynchronous. If you didn't use `setTimeout` and just called `.appendChild` in the same `for` loop, you'd see them all appear at once, because the code is synchronous and there will only be one repaint at the end. I'm not sure if that's all even related anymore :) – Ian May 15 '13 at 03:04
  • The one thing I think I can say about this is that it depends on if you have code that expects the element to be in the DOM. For example, if you do: `var div = document.createElement("div"); appendElement(div);` and then expected `div` to be in the DOM, the code might not work properly, because it wouldn't be in the DOM yet – Ian May 15 '13 at 03:10

2 Answers2

6

I think you misunderstood the question. I read it as asking to append an element to the DOM, then delay any further processing until the next tick. Therefore:

document.appendChild(element);
setTimeout(function() {
    resumeProgramFlowFromHere();
}, 0);
// nothing here

That's useful when you want to make sure there is a reflow/repaint before some time-consuming operation takes place (to give users visual feedback). Browsers already force a repaint in certain circumstances, but when they don't, this technique can be useful.

You can find some more information here and here.


That's my interpretation of the question, but I find it confusing too, probably because it's not clear what they mean by events. And there are other debatable questions on that site, the weirdest being:

What is the concept of “functions as objects” and how does this affect variable scope?

That simply makes no sense to me. Okay, functions are objects in JavaScript, and scopes are also related to functions, but those are distinct topics. The fact that functions are objects has nothing to do with scope.

So my advice is, take those interview questions with a grain of salt.

Community
  • 1
  • 1
bfavaretto
  • 71,580
  • 16
  • 111
  • 150
0

There are situations where you run into bugs that require this technique to fix. Its not specific to appending an element though; that's just one use case.

I've encountered this from time to time doing particular kinds of animations where setting multiple css3 properties at the same time doesn't trigger the browser to redraw correctly.

While I don't have code examples of the previous case, you can see where I use the technique on my site http://popped.at. Look in this file, http://www.popped.at/js/main.js, and search for "//the 0ms timeout is needed for IE9". In this case, there was an issue in IE9 where canvas wasn't being updated properly.

(The site isn't functioning in the backend at the moment, which is why its dark. I'm working on that.)

Geuis
  • 41,122
  • 56
  • 157
  • 219