-2
document.write('Test.');
while (true) 1;

I want the browser to show the text first, and jump into the infinite loop then. But I don't see any text. How to force the browser to go line by line? I'm looking for a simple function that tells the browser to wait for the first line to finish. Is there such a thing? Like waitForEverythingToFinish(). Like using window.getComputedStyle(div).getPropertyValue('height') to force a repaint.

Tamás Bolvári
  • 2,976
  • 6
  • 34
  • 57
  • 2
    Even before the browser tries to "display", the browser enters the infinite loop and gets stalled. And please, do not use `document.write()`. – Praveen Kumar Purushothaman Nov 07 '16 at 02:23
  • How can this be changed? It's just an extremely simplified illustration of the problem. The real code doesn't contain any `document.write()`. – Tamás Bolvári Nov 07 '16 at 02:23
  • 1
    @TamásBolvári Don't do it? Why would you want to stall out the browser? The tab will crash. – Brad Nov 07 '16 at 02:24
  • 2
    What do you wanna happen @TamásBolvári. Looks like an XY problem to me. – Praveen Kumar Purushothaman Nov 07 '16 at 02:25
  • This question is about the order of commands, not the specific commands. Of course I don't want to crash the browser in my real code. I just don't want to copy paste the whole file reading, image compressing stuff, because it's irrelevant. – Tamás Bolvári Nov 07 '16 at 02:26
  • the order is what you see - the problem is the infinite loop doesn't let the browser update what you see – Jaromanda X Nov 07 '16 at 02:27
  • Imagine the original example with a long task instead of an infinite loop. The text will still not display instantly. That's the problem. – Tamás Bolvári Nov 07 '16 at 02:29
  • @TamásBolvári A relevant code snippet doesn't have to include all of that. Show us the main flow, with function names calling out to stuff that compresses your images and reads files. It doesn't need to be your actual code for this question, but it's impossible to determine what it is you're trying to do from the question as-is. – Brad Nov 07 '16 at 02:29
  • 1
    @TamásBolvári You will have to restructure your code. If the call stack never completes, then the browser isn't going to update. You need to structure your code to let the browser come up for air. You might also consider web workers to put this on another thread. – Brad Nov 07 '16 at 02:30
  • Is there a way to force an "update"? – Tamás Bolvári Nov 07 '16 at 02:31
  • @TamásBolvári Yes... by letting your code complete to do the next iteration later. – Brad Nov 07 '16 at 02:31
  • @TamásBolvári Also look at `requestAnimationFrame()` ... again though, I have no way of knowing if that's appropriate for your situation. – Brad Nov 07 '16 at 02:32

2 Answers2

1

I believe the essence of this question, based on your comments, is that you want to be sure the browser has time to update the screen before it starts a long-running synchronous task. The browser updates the screen when it can, so if you block the main thread, you can't get a refreshed UI. This should be possible with a simple timeout, or as comments have suggested, requestAnimationFrame.

Simple Timeout:

// For example, document.write(...)
funcThatChangesScreen();

setTimeout(function () {
  // For example, lots of heavy calculations
  synchronousFuncThatTakesALongTime();
}, 100);

JSFiddle comparison:

Or, see requestAnimationFrame.

Edit: As others in the comments have noted, this is not truly the best way to get what you want, even if it does work. If you have a long-running synchronous task, it may be best to delegate it to a WebWorker or make it asynchronous. This timeout solution will allow the user to see the text on the screen, but it will still block the UI after, like in the JSFiddles above.

Andrew Messier
  • 806
  • 9
  • 10
  • Why can't the browser update the screen when I want it to do so, what is it waiting for? Whatever it's waiting for, there should be a way to stop it. It isn't even busy yet, when I ask it to `document.write('Test.');`. Anyway, you've answered my question perfectly, but could you add this: [with requestAnimationFrame](https://jsfiddle.net/ruLf0rkg/2/)? – Tamás Bolvári Nov 07 '16 at 05:12
  • 1
    @TamásBolvári - The browser can only do one thing at a time, including paint the screen for users to see. Browsers try to be smart by waiting until they have nothing else to do to refresh the screen UI - otherwise, the constant repainting after almost every single line of code would make everything much slower. For more info, see [this answer on JS multithreading](http://stackoverflow.com/questions/7909593/is-it-possible-to-thread-javascript-and-keep-access-to-the-ui). A discussion of requestAnimationFrame is [here](https://css-tricks.com/using-requestanimationframe/). – Andrew Messier Nov 07 '16 at 12:38
-1

See if this work for your purpose?

if(!document.write('Test.')){
    while (true) 1;
}
Bowie
  • 992
  • 3
  • 10
  • 25