问题
In using javascript i noticed this thing. You can use
var i=0;
var startingTime=new Date().getTime();
setInterval("foo()",1);
function foo() {
i+=1;
if ($("#foodiv").text()==i) {
//we detected a doubled value (parallel execution)
$("#repdiv").append("[repetition on "+i+"]");
}
$("#foodiv").html(i);
$("#timediv").html(Math.floor((new Date().getTime()-startingTime)/1000));
}
but as i read and try myself the time is not 1ms , it's at least 10ms or something. In fact after 10 seconds, i have a value of i around 2300/2400 , and not 10000 as expected.
This is the minimum possible time factor for the procedure ??? certainly NO. If i try this :
<html><head>
<script language="javascript" type="text/javascript" src="jquery-1.4.min.js"></script>
<script type="text/javascript">
var i=0;
var startingTime=new Date().getTime();
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
setInterval("foo()",1);setInterval("foo()",1);setInterval("foo()",1);
function foo() {
i+=1;
if ($("#foodiv").text()==i) {
//we detected a doubled value (parallel execution)
$("#repdiv").append("[repetition on "+i+"]");
}
$("#foodiv").html(i);
$("#timediv").html(Math.floor((new Date().getTime()-startingTime)/1000));
}
</script>
</head>
<body>
<div id="foodiv"></div> (counter)
<br/>
<div id="timediv"></div> (seconds passed)
<br/>
<div id="repdiv"></div>
<br/>
</body>
</html>
The counter will go very fast, and after 10 seconds, i have a value of 12000 !!!!. That's for me is unexplicable, because the call is not executed in parallel (or at least we could have some doubled readed values of i for different calls, figuring in the repdiv div).
Can someone explain me that ? I know the cpu is very stressed by all those calls, but at least it speed up things surprisingly.
I read all your responses and the other quests in the forum, and they confirmed my thinking. But the real question is Why ! Why they set the limit to 15ms when i can do multiple sequential calls obtaining a time much lower ? I'm sure this multiple callback system is not good practice, but i can do it, and i potentially can saturate cpu load.
回答1:
No, Javascript is single threaded. When you run setInterval or setTimeout, an event is generated which is then added to the browser's execution queue. So while you cannot guarantee that the code itself will run exactly when you want it to run, you can be sure that the event will be generated each time it is supposed to be generated. So in this case, you have 12 events that are being generated really close to each other. I notice that you've used 1 as the interval value. However, the minimum values in most browsers is around 15 (see here for more information.) The browser will run through the events in the order they are in the execution queue (in setInterval, the events try to play catch up. Look at the answer that Marcel linked to, for more details).
What this means is that in the first scenario you have one event generated every 15 or so milliseconds. So the counter is incremented more slowly. But in the second case, you have twelve events that are fired pretty close to each other every 15 or so milliseconds, and so the counter increments much faster.
回答2:
JavaScript timer values are set to at least 15ms in most browsers, even if a smaller value is given. AFAIK only Google Chrome uses 4ms. See also the accepted answer of How to determine the best "framerate" (setInterval delay) to use in a JavaScript animation loop? .
回答3:
No, JavaScript has no multithreading, at least not at the moment.
Please read this answer to see how setInterval works.
回答4:
The code that you posted doesn't run, here is the corrected code:
var i=0;
setInterval(foo,1);
function foo() {
i+=1;
if ($("#foodiv").text()==i) {
//we detected a doubled value (parallel execution)
$("#repdiv").append("[repetition on "+i+"]");
}
$("#foodiv").html(i);
}
If you look at the CPU performance while the code runs, you see that it's barely working at all, which means that the lower rate is not due to the code being busy. It simply won't fire the interval as often as you requested.
(If you start twelve intervals, the load is still barely noticable. I started 200 intervals before getting a load close to 100% on one of the cores.)
The browser uses some sort of clock to determine which intervals should be fired, and that clock usually has a lower resolution than milliseconds. So, the interval will not fire again until the next clock tick, which in your case seem to be about 15 ms apart.
回答5:
The second value passed to the setInterval method is indeed a minimum value. Although 1 represents 1 millisecond and it's unlikely that most browsers will give you exactly this timeout. Another answer says it's more likely to be around 15 milliseconds.
Even so, the second item being a minimum value adequetely explains the first sample.
The second sample is also explained by this behavior. Each of the setInterval methods you calls registers a completely separate call back. They each have a minimum of 1 but no dependency on each other. So it's perfectly valid for all of them to fire within the same 1 millisecond interval (as long as each one itself waits 1 millisecond before re-firing).
来源:https://stackoverflow.com/questions/4037738/does-this-behavior-of-setinterval-imply-multithreading-behavior-in-javascript