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
212 views
in Technique[技术] by (71.8m points)

javascript - setTimeout behaviour with blocking code

This is my test code (fiddle here):

console.log('Before wait');
setTimeout(function () { console.log('Yo!'); }, 1000);
var start = Date.now();
while (Date.now() < start + 3000) {}
console.log('After wait');

This is the timeline of events in Chrome:

  • Time 0 seconds: Prints "Before wait"
  • Time 3 seconds: Prints "After wait", and then immediately after "Yo!"

Is this behaviour according to spec? Why is it not

  • Time 0 seconds: Prints "Before wait"
  • Time 3 seconds: Prints "After wait"
  • Time 4 seoncds: Prints "Yo!"

?

See Question&Answers more detail:os

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

1 Reply

0 votes
by (71.8m points)

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.


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

...