setTimeout behaviour with blocking code

后端 未结 4 1410
无人及你
无人及你 2020-11-29 08:01

This is my test code (fiddle here):

console.log(\'Before wait\');
setTimeout(function () { console.log(\'Yo!\'); }, 1000);
var start = Date.now();
while (Dat         


        
相关标签:
4条回答
  • 2020-11-29 08:16

    Not sure if it could help you but this problem's been explained in: https://developer.mozilla.org/en-US/docs/Web/JavaScript/EventLoop#Run-to-completion

    For this reason, the second argument indicates a minimum time—not a guaranteed time.

    0 讨论(0)
  • 2020-11-29 08:21

    When you run the busy-waiting loop after the setTimeout call, you don't let time for your "Yo!" to print out, because the Javascript runtime is busy with your loop (actualy the empty statement also makes it busy because of continues evaulaation of the loop condition).

    You should always avoid such a busy-waiting loop, because until that finishes, nothing else can be called or run in that window.

    0 讨论(0)
  • 2020-11-29 08:32

    The delay of setTimeout is relative to the exact point in time when it is called. It expires while you are still busy waiting. So it will be performed at the next instant where the control goes back into the event loop.

    Edit:

    The spec is a bit vague in this point, but I guess it's the intended and only straightforward interpretation:

    setTimeout(function, milliseconds)

    This method calls the function once after a specified number of milliseconds elapses, until canceled by a call to clearTimeout. The methods returns a timerID which may be used in a subsequent call to clearTimeout to cancel the interval.

    0 讨论(0)
  • 2020-11-29 08:40

    JavaScript is single-threaded. If some block of code uses execution thread, no other code can be executed. This means your setTimeout() call must wait until main execution (the one with busy-waiting while loop) finishes.

    Here is what happens: you schedule setTimeout() to execute after a second and then block main thread for 3 seconds. This means the moment your busy loop finishes, timeout is already 2 seconds too late - and JS engine tries to keep up by calling your timeout as soon as possible - that is, immediately.

    In fact this:

    while (Date.now() < start + 3000) {}
    

    is one of the worst things to do in JavaScript. You hold JavaScript execution thread for 3 seconds and no other event/callback can be executed. Typically browsers "freeze" in that period of time.

    0 讨论(0)
提交回复
热议问题