在javascript中使用SetTimeOut运行更新UI的函数时浏览器冻结

在javascript中使用SetTimeOut运行更新UI的函数时浏览器冻结,javascript,settimeout,Javascript,Settimeout,我使用下面提到的代码调用FunctionalDDCard,它将图像添加到网页中。浏览器因此冻结。如果我调用了一个简单的函数,它在setTimeOut中不更新UI,那么浏览器就不会冻结。所以,我们不能在setTimeOut回调函数中更新UI。据我所知,浏览器的javascript运行时是单线程的。因此,没有单独的UI线程。那为什么浏览器会冻结?因为回调将在主线程中运行。代码如下: while(user.Score > dealer.Score){ setT

我使用下面提到的代码调用FunctionalDDCard,它将图像添加到网页中。浏览器因此冻结。如果我调用了一个简单的函数,它在setTimeOut中不更新UI,那么浏览器就不会冻结。所以,我们不能在setTimeOut回调函数中更新UI。据我所知,浏览器的javascript运行时是单线程的。因此,没有单独的UI线程。那为什么浏览器会冻结?因为回调将在主线程中运行。代码如下:

 while(user.Score > dealer.Score){
        
        setTimeout(function(){addCard(dealer);},2000);
    }

由于user.Score>dealer.Score永远不会为假,所以您陷入了无限循环。此外,由于每2秒调用同一个函数,因此会得到递归,这会自行创建递归。浏览器内存不足,被卡住。

您的浏览器陷入无限循环,因为user.Score>dealer.Score永远不会为false。此外,由于每2秒调用同一个函数,因此会得到递归,这会自行创建递归。浏览器内存不足,会卡住。

浏览器冻结的简单解释是浏览器资源不足

由于addCarddealer函数在setTimeout之外工作,因此我认为超时的实现是原因。最明显的一点是UI更新的完成时间比线程可用的时间要长。由于while循环将继续执行,因此最终调用堆栈将填满。这也将解释为什么浏览器冻结而不抛出任何错误


您应该能够通过调试代码来确认此行为。但是,我建议您修改逻辑,而不是尝试解决该问题。

浏览器冻结的简单解释是浏览器资源不足

由于addCarddealer函数在setTimeout之外工作,因此我认为超时的实现是原因。最明显的一点是UI更新的完成时间比线程可用的时间要长。由于while循环将继续执行,因此最终调用堆栈将填满。这也将解释为什么浏览器冻结而不抛出任何错误


您应该能够通过调试代码来确认此行为。但是,我建议您修改逻辑,而不是尝试解决该问题。

但是如果我调用一个简单的函数,它会将某些内容记录到控制台。那么这个问题就不会发生了。根据这个推理,这也应该冻结浏览器。但如果我调用一个简单的函数,它会将某些内容记录到控制台。那么这个问题就不会发生了。根据这个推理,这也应该冻结浏览器。在导致浏览器冻结的场景中,您能估计循环执行的次数吗?另外,条件中的变量是如何递增的?@DelwynPinto条件中的变量在addCard函数中递增,该函数在setTimeOut调用中作为回调传递。在导致浏览器冻结的情况下,您能否估计循环的执行次数?另外,条件中的变量是如何递增的?@DelwynPinto条件中的变量在addCard函数中递增,该函数在setTimeOut调用中作为回调传递。不会调用addCard。所以,UI更新不能成为原因。啊,好的。这些信息完全改变了问题。我想我理解这个问题。循环持续触发调用堆栈上的setTimeOut。因此,调用堆栈从不为空。因此,回调队列中setTimeOut的回调函数永远不会被调用。它会导致无休止的循环。我想这就是@Or anasag试图在他的回答中说的。虽然这听起来很合乎逻辑,但这不是javascript中计时器的工作方式。另外,调用堆栈在我的解释中填满了,而不是在分析AG中。NodeJs文档对javascript中的计时器有很好的解释:addCard没有被调用。所以,UI更新不能成为原因。啊,好的。这些信息完全改变了问题。我想我理解这个问题。循环持续触发调用堆栈上的setTimeOut。因此,调用堆栈从不为空。因此,回调队列中setTimeOut的回调函数永远不会被调用。它会导致无休止的循环。我想这就是@Or anasag试图在他的回答中说的。虽然这听起来很合乎逻辑,但这不是javascript中计时器的工作方式。另外,调用堆栈在我的解释中填满了,而不是在分析AG中。NodeJs文档对javascript中的计时器有很好的解释: