Ensure only one setTimeout runs (is active) at a t

2019-07-16 07:24发布

问题:

The recursive setTimeout function getRandomProducts is called onload in the html body tag, and so is constantly iterating.

The function setCategoryTree is being called onclick from the links in a nested ul of a navigation-bar. This function then passes the variable mainCategory to getRandomProducts, in which the variable is declared globally to maintain its' initialization.

...So, what I am trying to do is reset the getRandomProducts function when a link is clicked in the navigation-bar, and pass the category name from the link that was clicked. However, clearTimeout does not seem to be working and so the iterations occur a lot more frequently as there are then multiple recursive loops executing simultaneously.

And not only that, but my global variables are not storing data from setCategoryTree as intended (basically I am trying to use the global variable similarly to a static-variable). I have discerned all of this behavior with the window.alert that is commented out.

Here is the relevant Javascript code:

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);
}

回答1:

You are setting the variable t within the function. The next time this function gets called the var t will not be available for you.

Therefore, Set the variable above the function (not in it)

var randomProductsTimeout = false;

function getRandomProducts(category){

    randomProductsTimeout = setTimeout()[..]