2010-09-03 19 views
45

Voglio forzare un programma JavaScript ad attendere in alcuni punti particolari della sua esecuzione fino a quando una variabile non è cambiata. C'è un modo per farlo? Ho già trovato un'estensione chiamata "JavaScript narrativo" che forza il programma ad attendere fino a quando un evento non si verifica. C'è un modo per creare un nuovo evento, un "evento di cambiamento variabile" ad esempio che si comporta come un evento onclick.Come posso fare in modo che un programma attenda una variazione variabile in javascript?

risposta

0

No dovresti creare la tua soluzione. Come usare il modello di progettazione di Observer o qualcosa del genere.

Se non hai il controllo sulla variabile o chi la sta usando, temo che tu sia condannato. EDIT: Oppure usa la soluzione di Skilldrick!

Mike

76

una soluzione facile e veloce va come questa:

var something=999; 
var something_cachedValue=something; 

function doStuff() { 
    if(something===something_cachedValue) {//we want it to match 
     setTimeout(doStuff, 50);//wait 50 millisecnds then recheck 
     return; 
    } 
    something_cachedValue=something; 
    //real action 
} 

doStuff(); 
+1

modificato ora, controlla ogni 50 ms e funziona per i non bool.è come ho detto il modo facile e veloce per farlo, segui questo link: http://stackoverflow.com/questions/1029241/javascript-object-watch-for-all-browsers (già pubblicato da @mplungjan) per un altro soluzione a prova di problemi approfondita. – aularon

+0

Penso che intendessi "qualcosa === qualcosa_cachedValue". Quindi funziona: http://jsfiddle.net/pEnYC/ – Skilldrick

+0

@Skilldrick, sì, volevo dire che l'ho risolto. Grazie per la correzione:) – aularon

5

mi sento di raccomandare un wrapper che gestirà il valore in corso di modifica. Per esempio si può avere funzione JavaScript, in questo modo:

​function Variable(initVal, onChange) 
{ 
    this.val = initVal;   //Value to be stored in this object 
    this.onChange = onChange; //OnChange handler 

    //This method returns stored value 
    this.GetValue = function() 
    { 
     return this.val; 
    } 

    //This method changes the value and calls the given handler  
    this.SetValue = function(value) 
    { 
     this.val = value; 
     this.onChange(); 
    } 


} 

E poi si può fare un oggetto fuori di esso che conterrà il valore che si desidera monitorare, e anche una funzione che verrà chiamato quando il valore diventa cambiato. Ad esempio, se si desidera ricevere un avviso quando il valore cambia, e il valore iniziale è 10, si dovrebbe scrivere il codice in questo modo:

var myVar = new Variable(10, function(){alert("Value changed!");}); 

Handler function(){alert("Value changed!");} sarà chiamato (se si guarda il codice) quando SetValue() è chiamato.

È possibile ottenere il valore in questo modo:

alert(myVar.GetValue()); 

È possibile impostare il valore in questo modo:

myVar.SetValue(12); 

E subito dopo, un avviso verrà visualizzato sullo schermo. Guarda come funziona: http://jsfiddle.net/cDJsB/

+0

Grazie per la risposta, ma non è esattamente quello che voglio. Guarda il mio commento ad aularon per favore! –

15

Gli interpreti JavaScript sono a thread singolo, quindi una variabile non può mai cambiare, quando il codice è in attesa in qualche altro codice che non modifica la variabile.

A mio parere sarebbe la soluzione migliore per avvolgere la variabile in un tipo di oggetto che ha una funzione getter e setter. È quindi possibile registrare una funzione di richiamata nell'oggetto che viene chiamato quando viene richiamata la funzione setter dell'oggetto. È quindi possibile utilizzare la funzione getter nella richiamata per recuperare il valore corrente:

function Wrapper(callback) { 
    var value; 
    this.set = function(v) { 
     value = v; 
     callback(this); 
    } 
    this.get = function() { 
     return value; 
    } 
} 

Questo potrebbe essere facilmente utilizzato in questo modo:

<html> 
<head> 
<script type="text/javascript" src="wrapper.js"></script> 
<script type="text/javascript"> 
function callback(wrapper) { 
    alert("Value is now: " + wrapper.get()); 
} 

wrapper = new Wrapper(callback); 
</script> 
</head> 
<body> 
    <input type="text" onchange="wrapper.set(this.value)"/> 
</body> 
</html> 
+2

Probabilmente la soluzione migliore se hai il controllo sulla variabile originale. – Skilldrick

+0

Grazie per la risposta, ma non è esattamente quello che voglio. Guarda il mio commento ad aularon per favore! –

+1

Come ho spiegato gli interpreti JavaScript sono a thread singolo. Non è possibile bloccare il thread e attendere che qualche altro thread modifichi una variabile, perché non c'è nessun altro thread che possa modificare una variabile. Nessun gestore di eventi JavaScript può essere eseguito mentre un altro è già in esecuzione. – Reboot

1

È possibile utilizzare proprietà:

Object.defineProperty MDN documentation

Esempio:

function def(varName, onChange) { 
    var _value; 

    Object.defineProperty(this, varName, { 
     get: function() { 
      return _value; 
     }, 
     set: function(value) { 
      if (onChange) 
       onChange(_value, value); 
      _value = value; 
     } 
    }); 

    return this[varName]; 
} 

def('myVar', function (oldValue, newValue) { 
    alert('Old value: ' + oldValue + '\nNew value: ' + newValue); 
}); 

myVar = 1; // alert: Old value: undefined | New value: 1 
myVar = 2; // alert: Old value: 1 | New value: 2 
Problemi correlati