Long task in Javascript
Why in the following code I see the whole page at once ? Th开发者_如何学Canks !
HTML:
<div></div>
CSS:
div {
width: 100px;
height: 300px;
border: 1px solid black;
text-align: center;
}
Javascript:
$(function() {
for (var i=0; i<15; i++) {
sleep(100);
$("div").append("<span>--- " + i + " ---<br /></span>");
}
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
});
Because Javascript on web browsers is single-threaded (although that's changing; see below) and virtually no browser updates its UI while the (main) Javascript thread is busy. All your sleep
function does is block everything for 100ms, it doesn't let the browser do anything else like update its UI (e.g., doesn't "yield").
There are a couple of ways to do what you're trying to do:
Use the new web workers stuff; but note that it's not widely-supported yet.
Make your loop a function that calls itself via
setTimeout
. That way, your code is yielding to the browser and letting it update its UI.
Here's a simple example of how you might apply #2 above to your code:
$(function() {
var i;
doOne();
function doOne() {
$("div").append("<span>--- " + i + " ---<br /></span>");
if (i++ < 15) {
setTimeout(doOne, 0); // <== Won't really be zero, browsers clamp it at ~10
}
}
});
If you have a lot of loop iterations (e.g., a couple of hundred instead of 15), it may well be worth doing a chunk of them on each iteration rather than yielding on each iteration; the yield takes a measureable time (typically ~10-15ms).
You need to hand over some processing time to the UI since javascript is single threaded, like this:
$(function() {
function appendDiv(i) {
$("div").append("<span>--- " + i + " ---<br /></span>");
if(i < 14)
setTimeout(function() { appendDiv(i+1); }, 100);
}
appendDiv(0);
});
You can see a demo here
You could also use an interval for what you want, like this:
$(function() {
var i = 0;
var interval = setInterval(function() {
$("div").append("<span>--- " + i++ + " ---<br /></span>");
if(i == 15) clearInterval(interval);
}, 100);
});
精彩评论