0

该函数在不启动循环的情况下连续运行。

setTimeout 是为了允许 refreshTags 函数运行。

我敢肯定这不是写得最好的脚本——我不是大师——但是关于为什么这个脚本在无限循环中运行的任何想法?

function addTag() 
{
console.log('running'); 
refreshTags(); 
var t = document.getElementById('existingTags').textContent.match(/tag1/); 
var u = 'tag1'; 
if (t == u) {alert('This ticket has already been resolved by our team.')}; 
if (t != u) 
    {
    refreshTags();
    setTimeout(function() 
    {
        document.getElementById('tagToAdd').value = 'tag1';
        document.getElementById('tagSubmit').click(); 
        alert('Ticket resolved!'); 
    }, 2000)
}; 
}

编辑:下面调用 addTag 的代码。

var resolveButton = document.createElement("a");
resolveButton.href = '#';
resolveButton.innerHTML = '<span>Resolve</span>';
resolveButton.setAttribute("onClick", "addTag()");
resolveButton.setAttribute("type", "button");
resolveButton.setAttribute("class", "button1");

var cha = document.getElementById('chatter_view');
cha.parentNode.insertBefore(resolveButton, cha);
4

1 回答 1

0

与其试图回答为什么这段特定的代码有无限循环,我将尝试回答更大的问题“你如何防止和调试无限循环?”。

我发现的最好的防御方法之一是构建你的代码,这样控制总是朝着一个方向流动。您在这里有许多不同的层:

  • onclick 事件处理程序正在调用 addTag()
  • addTag() 正在调用 refreshTags()
  • addTag() 正在调用 setTimeout,它稍后会触发对 DOM 的点击。

保持代码向一个方向流动的一个简单方法是创建专用的事件处理程序,例如resolveButtonOnclick() { addTag() }. resolveButtonOnclick 只能从 resolveButton 的 onclick 处理程序中调用。这使得审核您的代码变得更加容易。您已经console.log('running')在 addTag() 函数的顶部放置了一个。现在,如果您将 console.log() 放入 resolveButtonOnclick() 中,您将立即知道 onclick 处理程序是否包含在无限循环中。

我们看不到您的代码,但是如果 refreshTags() 调用 addTag() 您将有一个循环控制流——这些并不总是坏的,但您需要格外小心它们会在某个时候终止。

您可能拥有的最大循环控制流是 addTag() 正在使用 .click() 方法回调到 DOM。直接从 Javascript 提交表单或使用 XHR 会更好、更快、更简洁。

要调试此循环,您是使用 console.log()s 的正确途径之一。添加更多(例如,您调用 addTag() 的每个位置)并找出调用它的位置。您可以尝试的另一件事是使用 Chrome 的 DevTools:添加一个“调试器”;调用 addTag() 的顶部并检查堆栈跟踪。

于 2012-08-27T05:11:43.147 回答