set超时在“while”内会导致浏览器崩溃.我怎样才能避免它

setTimeout within 'while' causes a browser crash. How can I avoid it?

本文关键字:崩溃 浏览器 能避免 超时 while set      更新时间:2023-09-26

我是编码新手,我想用HTML,CSS和Javascript构建一个Text Adeventure Game。我想显示数组中的许多文本和平,每个文本之间有一定的时间。由于 setTimeout,我尝试了不同的方法来避免无限循环,但我没有弄清楚如何将它应用于我的代码。

这是我的代码,导致崩溃:

var iCounterText = 0;
var verzog = function() {
  document.getElementById('toggleText').insertAdjacentHTML('beforeBegin', '<br>--------------<br>');
  document.getElementById('toggleText').insertAdjacentHTML('beforeBegin', part1[iCounterText]);
  iCounterText = iCounterText + 1;
  playaudio();
}
function forwardingLinks() {
  while (iCounterText < part1.length - 1) {
    setTimeout(verzog, 500); // Here is the problem //
  }
  document.getElementById('buttonLinks').innerHTML = part1[part1.length - 1];
}

以下代码工作正常,但文本之间没有超时:

function forwardingLinks() {
  while (iCounterText < part1.length - 1) {
    verzog();
  }
  document.getElementById('buttonLinks').innerHTML = part1[part1.length - 1];
}

编辑:这是我使用"setInterval"的新代码。问题:值由 1 相加,但函数未使用 part2 数组。相反,它再次使用 part1 数组,尽管 partvalue 已经包含 part2 数组。

var part1 = [                          //Texte und Antworten
'Hallo?',
'Test?',
'What',
'hello',
'--------------',
'Was?'
];
var part2 = [                          //Texte und Antworten
'part2 goes on....',
'bla bla',
'blablabla'
];
var iCounterText = 0;                           
var value = 1;
var partvalue = eval("part" + value);
function forwardingLinks() { 
var verzog = setInterval(function(){
if(iCounterText < partvalue.length-2){
++iCounterText;
toggleText.insertAdjacentHTML('beforeBegin', '<br>--------------<br>');
toggleText.insertAdjacentHTML('beforeBegin', partvalue[iCounterText]);
playaudio();
}else{
    buttonLinks.innerHTML = partvalue[partvalue.length-1];
    ++value;
    iCounterText=0;
    clearInterval(verzog);
}
},500);
}

你误解了 while 循环的流程。JavaScript 在单线程环境中运行。这意味着在forwardingLinks函数完成之前,对verzog函数的调用不会运行,但forwardingLinks函数永远不会完成,因为您的 while 循环依赖于永远不会增加的计数器,因为verzog尚未运行。

更改while循环,以便 iCounterText 变量从循环内递增,以便循环可以结束,然后对事件队列中堆叠的verzog的调用可以开始运行。

此外,由于您使用的是数字计数器,因此常规for循环比while循环更好,因为循环的步长值 ( ++iCounterText ) 是必需的:

 for(var iCounterText = 0; iCounterText < part1.length; ++iCounterText) {
   setTimeout(verzog, 500); 
 }

除了您的主要问题之外,一遍又一遍地重复扫描 DOM 以查找相同的元素是非常低效的,就像您在 verzog 函数中所做的那样。 相反,只需获取一次 DOM 引用并将其存储在可以重用的变量中:

 // Declare a variable in a scope that is accessible throughout your code
 var toggleText = null, buttonLinks = null;
 // Set up a callback that runs after the DOM is ready
 window.addEventListener("DOMContentLoaded", function(){
      // Scan the DOM for the element(s) you'll be needing
      toggleText = document.getElementById('toggleText');
      buttonLinks = document.getElementById('buttonLinks');
 });
 function verzog() {
   // Now, you can just refer to the DOM element you've already found:
   toggleText .insertAdjacentHTML('beforeBegin', '<br>--------------<br>');
   toggleText .insertAdjacentHTML('beforeBegin', part1[iCounterText]);
   playaudio();
 }
 function forwardingLinks() {
    for(var iCounterText = 0; iCounterText < part1.length; ++iCounterText) {
      setTimeout(verzog, 500); 
    }
    // Now, you can just refer to the DOM element you've already found:
    buttonLinks.innerHTML = part1[part1.length - 1];
 }