2012-01-11 2 views
5

Desidero distribuire il mio codice come funzioni anonime autoinvitanti, come vedo fare molti. Inoltre, nel mio codice devo monitorare per un altro caricamento della lib, quindi posso usarlo quando è disponibile.setTimeout() sulla funzione ricorsiva all'interno di una funzione autoinvitante

(function(window, document, undefined) { 
    staffHappens(); 
    var initMyLib = function() { 
    if (typeof(myLib) == 'undefined') { 
     setTimeout("initMyLib()", 50); 
    } else { 
     useMyLib(); 
    } 
    } 
    moreStaffHappens(); 
    initMyLib(); //-> initMyLib is undefined 
})(this, document); 

Come si può verificare questo errore? InitMyLib dovrebbe essere incluso nell'ambito della funzione di inclusione (autoinviante)?

risposta

11

cambiamento setTimeout("initMyLib()", 50); a setTimeout(initMyLib, 50);

Quando si passa una stringa come argomento si cercherà di valutare quando il timeout viene sparato, ma verrà eseguito in ambito globale. E il tuo metodo non esiste nell'ambito globale.


Demo ahttp://jsfiddle.net/gaby/zVr7L/

+0

che non dovrebbe effettuare il luogo in cui è 'undefined' però ... – Ktash

+0

@kTash, non non dovrebbe, ma sei sicuro che la parte' undefined' proviene da quella linea e non un esecuzione del script di timeout? –

+0

Non lo so. Questa è la frase che ha affermato che accade, quindi immagino che abbia fatto il debug per capire molto ... Questa è stata la prima cosa che ho pensato, ma se si verifica alla riga specificata e non nel timeout, allora non sono sicuro che sia giusto Stavo semplicemente pensando ad alta voce – Ktash

1

Si potrebbe anche usare una vera e propria funzione anonima per evitare scoping questioni:

(function() { 
    if(typeof(myLib) == 'undefined') 
     setTimeout(arguments.callee, 50); 
    else 
     // loaded 
})() 
+1

Una soluzione valida ma poiché 'arguments.callee' è deprecato nelle versioni javascript recenti, dovresti evitare di usarlo e usare quello suggerito che è chiamato funzioni .. Questo potrebbe anche essere fatto con' (function name() {'e poi usa' setTimeout (name, 50); ' –

+0

@Gaby aka G. Petrioli: lo so.Tuttavia,' callee' è una caratteristica interessante che vale la pena conoscere. – georg

+0

infatti è ... –

2

provare a leggere questa risposta per qualche indizio: recursive function vs setInterval vs setTimeout javascript

Questo è il codice di esempio da quella risposta:

/* 
this will obviously crash... and all recursion is at risk of running out of call stack and breaking your page... 

function recursion(c){ 
    c = c || 0; 
    console.log(c++); 
    recursion(c); 
} 
recursion(); 

*/ 

// add a setTimeout to reset the call stack and it will run "forever" without breaking your page! 
// use chrome's heap snapshot tool to prove it to yourself. :) 

function recursion(c){ 
    setTimeout(function(c){ 
     c = c || 0; 
     console.log(c++); 
     recursion(c); 
    },0,c); 
} 

recursion(); 

// another approach is to use event handlers, but that ultimately uses more code and more resources