我们需要时常将控制权释放给浏览器,以避免垄断浏览器的注意力。
释放控制的一种方法是使用setTimeout
,它安排在某个时间段调用“回调”。例如:
var f1 = function() {
document.body.appendChild(document.createTextNode("Hello"));
setTimeout(f2, 1000);
};
var f2 = function() {
document.body.appendChild(document.createTextNode("World"));
};
在此处调用f1
会将单词添加hello
到您的文档中,安排待处理的计算,然后将控制权释放给浏览器。最终,f2
将被调用。
请注意,在整个程序中不加选择地洒在整个程序中是不够的,setTimeout
就好像它是神奇的小精灵尘埃:您确实需要将其余的计算封装在回调中。通常,setTimeout
将是函数中的最后一件事,其余的计算填充到回调中。
对于您的特定情况,需要将代码仔细转换为以下内容:
var heavyWork = function(i, onSuccess) {
if (i < 300) {
var restOfComputation = function() {
return heavyWork(i+1, onSuccess);
}
return doSomethingHeavy(i, restOfComputation);
} else {
onSuccess();
}
};
var restOfComputation = function(i, callback) {
// ... do some work, followed by:
setTimeout(callback, 0);
};
这将在每个restOfComputation
.
作为另一个具体示例,请参阅:如何将一系列声音 HTML5 <audio> 声音剪辑排队以按顺序播放?
高级 JavaScript 程序员需要知道如何进行这种程序转换,否则他们会遇到您遇到的问题。您会发现,如果您使用这种技术,您将不得不以一种特殊的风格编写程序,其中每个可以释放控制的函数都接收一个回调函数。这种风格的技术术语是“延续传递风格”或“异步风格”。