Javascript 确保一次只运行一个setTimeout(处于活动状态)?

Javascript 确保一次只运行一个setTimeout(处于活动状态)?,javascript,recursion,global-variables,settimeout,function-call,Javascript,Recursion,Global Variables,Settimeout,Function Call,递归的setTimeout函数getRandomProducts在html body标记中被称为onload,因此不断迭代。函数setCategoryTree从导航栏嵌套ul中的链接被称为onclick。然后,此函数将变量mainCategory传递给getRandomProducts,在该函数中,变量被全局声明以保持其“初始化”。……因此,我试图在导航栏中单击链接时重置getRandomProducts函数,并从单击的链接传递类别名称。但是,clearTimeout似乎不起作用,因此迭代发生得

递归的
setTimeout
函数getRandomProducts在html body标记中被称为
onload
,因此不断迭代。

函数setCategoryTree从导航栏嵌套ul中的链接被称为
onclick
。然后,此函数将变量mainCategory传递给getRandomProducts,在该函数中,变量被全局声明以保持其“初始化”。

……因此,我试图在导航栏中单击链接时重置getRandomProducts函数,并从单击的链接传递类别名称。但是,
clearTimeout
似乎不起作用,因此迭代发生得更频繁,因为同时执行了多个递归循环。

不仅如此,而且我的全局变量没有按预期存储来自setCategoryTree的数据(基本上,我尝试使用与静态变量类似的全局变量)。我已通过注释掉的
窗口。alert
识别出所有这些行为。

以下是相关的Javascript代码:

var mainCategory = ""; // initialized from setCategoryTree
var category = mainCategory;

function getRandomProducts(category)
{
    //window.alert(category);
    if(typeof category == "undefined")
        category = "all";
    else
        clearTimeout(t);

    var req = new XMLHttpRequest();

    var products = document.getElementById("products");

    req.onreadystatechange = function()
    {
        if( (req.readyState == 4) && (req.status == 200) )
        {
            var result = req.responseText;
            products.innerHTML = result;
        }
    }
    req.open("GET", "default.php?category=" + category, true);
    req.send(null);

    var t = setTimeout("getRandomProducts()", 1000);
}

function setCategoryTree(link)
{
    var categoryTree = document.getElementById("categoryTree");

    /* climbing the DOM-tree to get the category name (innerHTML of highest "a" tag) */
        mainCategory = link.parentNode.parentNode.parentNode.getElementsByTagName("a")[0].innerHTML;

    var subcategory = link.innerHTML;

    categoryTree.innerHTML = "-- " + mainCategory + "  -- " + subcategory;

    getRandomProducts(mainCategory);
}

您正在函数中设置变量
t
。下次调用此函数时,var
t
将不可用

因此,将变量设置在函数上方(不在函数中)


切勿将字符串传递给
setInterval()
setTimeout()
。这样做与使用
eval()
一样糟糕,并且在使用变量时会导致无法读取且可能不安全的代码,因为您需要将它们插入字符串而不是传递实际变量。正确的解决方案是
setInterval(function()){/*您的代码*)},毫秒)。这同样适用于
setTimeout()
。如果您只想在没有任何参数的情况下调用单个函数,还可以直接传递函数名:
setInterval(someFunction,毫秒)
(注意函数名后面没有
()
)(
t
clearTimeout
总是未定义)哇,谢谢大家的快速回复。我已经实现了您的所有建议,这纠正了
setTimeout/cleartimout
问题。。。但是在取消注释
窗口.alert时,会出现一些异常的正整数和负整数,而不是预期的字符串!有什么想法吗?你的回答很模糊。不知道问题出在哪里。如果我的答案对你有帮助的话,请你也把那一个标记为最好的。如果还有其他问题,请提出一个新问题。啊,我发现了——我错误地将全局变量作为参数传递,出现了一些奇怪的意外错误。谢谢大家的帮助。
var randomProductsTimeout = false;

function getRandomProducts(category){

    randomProductsTimeout = setTimeout()[..]