Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
764 views
in Technique[技术] by (71.8m points)

performance - How browser executes Javascript and renders asynchronously

Here is the code on jsfiddle

<script>
  function updateSync1() {
    for (var i = 0; i < 1000; i++) {
      document.getElementById('output').innerHTML = i;
    }
  }

  function updateSync2() {
    for (var i = 0; i < 1000; i++) {
      setTimeout(document.getElementById('output').innerHTML = i, 0);
    }
  }

  function updateAsync() {
    var i = 0;

    function updateLater() {
      document.getElementById('output').innerHTML = (i++);
      if (i < 1000) {
        setTimeout(updateLater, 0);
      }
    }

    updateLater();
  }
</script>

<div class="row btn_area">
  <button class="btn btn-info" onclick="updateSync1()">Run Sync 1</button>
  <button class="btn btn-info" onclick="updateSync2()">Run Sync 2</button>
  <button class="btn btn-info" onclick="updateAsync()">Run Async</button>
  <span class="label label-info pull-right" style="display:block;" id="output"></span>
</div>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Javascript execution is single-threaded. It uses a task queue and the stack to execute stuff.

This piece of code:

for (var i=0;i<length;i++) {
     setTimeout(drawChartFunc,0);
}

Will add [length] setTimeouts calls on the task queue and excute all of them subsequently (0 ms timeout). Only the last operation will update the the screen, because all of the timeout tasks come first on the stack (after the loop, the task queue contains [length] setTimeout calls). Every timeout executes drawChartFunc. Now drawChartFunc does put a screen update function on the task queue, but the remaining timeouts come first, so first the next timeout is executed - the screen update functions can only be executed after the [length] setTimeout calls are finished (taken of the task queue/stack). This is also done subsequently, but very fast. If your eyes where trained to see nanosecond transitions, you may have spotted the subsequent numbers in the output ;)

Now

function updateLater() {
     drawChartFunc();
     i++;
     if (i < length) { 
         setTimeout(updateLater, 0);
     }
 }

Will first run drawChartFunc putting the screen update on the task queue, then put increment i on the task queue and - if applicable - after that add a new setTimeout to the task queue. In other words, drawChartFunc is put on the stack, that puts the screen update on the stack, both are executed, an subsequently the timeout is put on the stack, putting drawChartFunc on the stack ... etc.

Concering the javascript task queue/stack: this video was really useful to me.

Here's your jsFiddle, rewritten a bit. It shows you the queuing process for both methods.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...