Javascript 为什么UI操作在计算之后运行,即使两者交替?
我的问题更复杂,但我得出了一个简单而简洁的例子: HTML:Javascript 为什么UI操作在计算之后运行,即使两者交替?,javascript,jquery,Javascript,Jquery,我的问题更复杂,但我得出了一个简单而简洁的例子: HTML: First: 然后: 然后: 然后: 然后: JS(+jQuery(如果有问题)): $(文档).ready(函数(){ doStuff(); }); 函数doStuff(){ $(“#first”).text(新日期().getSeconds()); var i=1; 而(i
First:
然后:
然后:
然后:
然后:
JS(+jQuery(如果有问题)):
$(文档).ready(函数(){
doStuff();
});
函数doStuff(){
$(“#first”).text(新日期().getSeconds());
var i=1;
而(i<100000000){
i++;
}
$(“#秒”).text(新日期().getSeconds());
var i=1;
而(i<100000000){
i++;
}
$(“#第三”).text(新日期().getSeconds());
var i=1;
而(i<100000000){
i++;
}
$(“#第四”).text(新日期().getSeconds());
var i=1;
而(i<100000000){
i++;
}
$(“#第五”).text(新日期().getSeconds());
}
和
从这个例子中,我的直觉告诉我,$(“#第一”)
应该在$(“#第五”)
之前接收文本值。然而,它们都同时出现。不,这不是JS运行得很快的问题,正如您在示例中看到的那样,$(“#第一”)
的值比$(“#第五”)
的值低约2秒
为什么会发生这种情况(什么!),存在什么解决方案 javascript阻止页面呈现,因此在所有javascript块完成之前,它不会呈现html输出。javascript阻止页面呈现,因此在所有javascript块完成之前,它不会呈现html输出。javascript在UI完成之前阻止它。它应该是一种单线程语言,但是(如中所述)并没有那么简单 问题的解决方法是使用
setTimeout
。请参阅(该示例不适用于复制粘贴,但我相信它足以说明此想法):
$(文档).ready(函数(){
doStuff();
});
函数doStuff(){
$(“#first”).text(新日期().getSeconds());
var i=1;
setTimeout(函数(){
而(i<100000000){
i++;
}
$(“#秒”).text(新日期().getSeconds());
}, 0);
}
setTimeout
确保doStuff
功能完成,然后浏览器处理DOM更改,然后执行另一个功能(传递给setTimeout
方法)
可以找到一个关于为什么事情会以这种方式发生的简洁明了的解释(感谢您提供链接)。简单而简短:当JS处理
doStuff
方法时,UI被阻塞(由于其单线程性质)。调用setTimeout
,将第二个参数设置为0毫秒,会(立即)将另一段代码放入处理队列(setTimeout的第一个参数)。然后doStuff
方法完成。JS然后处理队列中的下一项,这显然是UI更新。同样,当UI更新完成时,队列中的下一项是通过setTimout
调用添加到队列中的内容。JavaScript在UI完成之前阻止它。它应该是一种单线程语言,但是(如中所述)并没有那么简单
问题的解决方法是使用setTimeout
。请参阅(该示例不适用于复制粘贴,但我相信它足以说明此想法):
$(文档).ready(函数(){
doStuff();
});
函数doStuff(){
$(“#first”).text(新日期().getSeconds());
var i=1;
setTimeout(函数(){
而(i<100000000){
i++;
}
$(“#秒”).text(新日期().getSeconds());
}, 0);
}
setTimeout
确保doStuff
功能完成,然后浏览器处理DOM更改,然后执行另一个功能(传递给setTimeout
方法)
可以找到一个关于为什么事情会以这种方式发生的简洁明了的解释(感谢您提供链接)。简单而简短:当JS处理
doStuff
方法时,UI被阻塞(由于其单线程性质)。调用setTimeout
,将第二个参数设置为0毫秒,会(立即)将另一段代码放入处理队列(setTimeout的第一个参数)。然后doStuff
方法完成。JS然后处理队列中的下一项,这显然是UI更新。同样,当UI更新完成时,队列中的下一项是通过setTimout
调用添加到那里的内容。这是我的输出:首先是42,然后是42,然后是43,然后是43,然后是44,我无法理解的是JavaScript是单线程语言。您的while循环正在冻结UI。Webworkers可能是一个解决方案,但事实上,您无法从worker访问DOM,因此这实际上取决于您的实际用例。使用timeout可能是另一种解决方案,但它只是一种解决方法。我怀疑您看到的问题是特定于浏览器的bug。使用chrome时,我先得到:38,然后是:39,然后是:40,然后是:41,然后是:43@bhspencer但是你一次就得到了,不是一个接一个。这就是这里的所有问题,如果我是正确的:$(“#first”)应该在Javascript中的$(“#fifth”)
操作符同时处理之前获取其文本值,而不是像PHPthats一样我的输出:首先是42,然后是42,然后是43,然后是43,然后是44,奇怪的是我无法获得单线程语言。您的while循环正在冻结UI。Webworkers可能是一个解决方案,但事实上,您无法从worker访问DOM,因此这实际上取决于您的实际用例。使用timeout可能是另一种解决方案,但它只是一种解决方法。我怀疑您看到的问题是特定于浏览器的bug。使用chrome时,我先得到:38,然后是:39,然后是:40,然后是:41,然后是:43@bhspencer但是你一次就得到了,不是一个接一个。如果我没记错的话,这就是这里的全部问题:$(“#first”)应该得到它的
First: <span id="first"></span> <br/>
Then: <span id="second"></span> <br/>
And then: <span id="third"></span> <br/>
And then: <span id="fourth"></span> <br/>
And then: <span id="fifth"></span>
$(document).ready(function() {
doStuff();
});
function doStuff() {
$("#first").text(new Date().getSeconds());
var i = 1;
while (i < 1000000000) {
i++;
}
$("#second").text(new Date().getSeconds());
var i = 1;
while (i < 1000000000) {
i++;
}
$("#third").text(new Date().getSeconds());
var i = 1;
while (i < 1000000000) {
i++;
}
$("#fourth").text(new Date().getSeconds());
var i = 1;
while (i < 1000000000) {
i++;
}
$("#fifth").text(new Date().getSeconds());
}
$(document).ready(function() {
doStuff();
});
function doStuff() {
$("#first").text(new Date().getSeconds());
var i = 1;
setTimeout(function() {
while (i < 1000000000) {
i++;
}
$("#second").text(new Date().getSeconds());
}, 0);
}