1

Die rekursive setTimeout-Funktion getRandomProducts heißt onload im HTML-Body-Tag und wird daher ständig iteriert.

Die Funktion setCategoryTree heißt onclick von den Links in einer verschachtelten UL einer Navigationsleiste. Diese Funktion übergibt dann die Variable mainCategory an getRandomProducts, in der die Variable global deklariert wird, um ihre Initialisierung beizubehalten.

... Ich versuche also, die getRandomProducts-Funktion zurückzusetzen, wenn auf einen Link in der Navigationsleiste geklickt wird, und den Kategorienamen von dem Link zu übergeben, auf den geklickt wurde. clearTimeout scheint jedoch nicht zu funktionieren, und die Iterationen treten viel häufiger auf, da dann multiple rekursive Schleifen gleichzeitig ausgeführt werden.

Und nicht nur das, aber meine globalen Variablen speichern keine Daten aus setCategoryTree wie beabsichtigt (grundsätzlich versuche ich, die globale Variable ähnlich wie eine statische Variable zu verwenden). Ich habe all dieses Verhalten mit der window.alert erkannt, die auskommentiert ist.

Hier ist der relevante Code Javascript:

Sicherstellen, dass nur ein setTimeout gleichzeitig ausgeführt wird (ist aktiv)?

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

** ** nie eine Zeichenfolge 'setInterval()' oder 'setTimeout()' übergeben. Dies ist genauso schlimm wie die Verwendung von 'eval()' und führt zu unlesbarem und möglicherweise unsicherem Code, sobald Sie Variablen verwenden, da Sie sie in die Zeichenfolge einfügen müssen, anstatt die tatsächliche Variable zu übergeben. Die richtige Lösung ist 'setInterval (function() {/ * Ihr Code *)}, msecs);'. Dasselbe gilt für 'setTimeout()'. Wenn Sie nur eine einzige Funktion ohne Argumente aufrufen möchten, können Sie den Funktionsnamen auch direkt übergeben: 'setInterval (someFunction, msecs);' (Beachten Sie, dass hinter dem Funktionsnamen ** no ** '()' steht) – ThiefMaster

+1

('t' ist * immer * undefiniert bei' clearTimeout'.) –

+0

Wow, danke für die schnelle Antwort alle. Ich habe alle deine Vorschläge implementiert, und das hat das 'setTimeout/clearTimeout'-Problem korrigiert ... aber beim Auskommentieren des' window.alert' gibt es einige ungewöhnliche positive und negative Ganzzahlen anstelle der beabsichtigten Zeichenkette! Irgendwelche Ideen? –

Antwort

1

Sie die Variable t innerhalb der Funktion zu setzen. Beim nächsten Aufruf dieser Funktion steht Ihnen die Variable t nicht zur Verfügung.

Daher Setzen Sie die Variable über die Funktion (nicht drin)

var randomProductsTimeout = false; 

function getRandomProducts(category){ 

    randomProductsTimeout = setTimeout()[..]