2010-09-03 39 views
45

Quiero obligar a un programa JavaScript a esperar en algunos puntos particulares de su ejecución hasta que una variable haya cambiado. ¿Hay una manera de hacerlo? Ya he encontrado una extensión que se llama "JavaScript narrativo" que obliga al programa a esperar hasta que ocurra un evento. ¿Hay alguna manera de crear un nuevo evento, un "evento de cambio variable", por ejemplo, que se comporte como evento onclick ...¿Cómo puedo hacer que un programa espere un cambio de variable en javascript?

Respuesta

0

No, tendría que crear su propia solución. Como usar el patrón de diseño Observer o algo así.

Si no tiene control sobre la variable o quién la está utilizando, me temo que está condenada al fracaso. EDITAR: ¡O usa la solución de Skilldrick!

Mike

76

una solución rápida y sencilla es la siguiente:

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

editado ahora, comprueba cada 50 ms y funciona para booleanos.es como dije la forma rápida y fácil de hacerlo, siga este enlace: http://stackoverflow.com/questions/1029241/javascript-object-watch-for-all-browsers (publicado ya por @mplungjan) para obtener más información. solución a prueba de problemas en profundidad. – aularon

+0

Creo que quería decir 'something === something_cachedValue'. Entonces funciona: http://jsfiddle.net/pEnYC/ – Skilldrick

+0

@Skilldrick, sí que quería decir que, lo arreglé. Gracias por la corrección:) – aularon

5

Yo recomendaría un envoltorio que se encargará de valor que se cambió. Por ejemplo, puede tener una función de JavaScript, como esto:

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


} 

Y a continuación, puede hacer que un objeto fuera de él que contendrá el valor que desea supervisar, y también una función que se llama cuando el valor se pone cambiado Por ejemplo, si desea que se le avise cuando cambia el valor, y el valor inicial es de 10, podría escribir código como este:

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

Handler function(){alert("Value changed!");} se llama (si nos fijamos en el código) cuando SetValue() es llamado.

Puede obtener el valor de este modo:

alert(myVar.GetValue()); 

Puede establecer el valor de esta manera:

myVar.SetValue(12); 

E inmediatamente después, una alerta se mostrará en la pantalla. Vea cómo funciona: http://jsfiddle.net/cDJsB/

+0

Gracias por la respuesta, pero no es exactamente lo que quiero. Mira mi comentario a aularon por favor! –

15

Los intérpretes de JavaScript tienen una sola hebra, por lo que una variable nunca puede cambiar, cuando el código está esperando en algún otro código que no cambie la variable.

En mi opinión, sería la mejor solución para envolver la variable en algún tipo de objeto que tenga una función getter y setter. A continuación, puede registrar una función de devolución de llamada en el objeto que se llama cuando se llama a la función de establecimiento del objeto. A continuación, puede utilizar la función de captador en la devolución de llamada para recuperar el valor actual:

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

Esto podría ser utilizado fácilmente como esto:

<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

Probablemente la mejor solución si tienes control sobre la variable original. – Skilldrick

+0

Gracias por la respuesta, pero no es exactamente lo que quiero. Mira mi comentario a aularon por favor! –

+1

Como expliqué, los intérpretes de JavaScript tienen un solo hilo. No puede bloquear el hilo y esperar que otro hilo cambie una variable, porque no hay otro hilo que pueda cambiar una variable. No se puede ejecutar ningún controlador de eventos de JavaScript mientras otro ya está ejecutándose. – Reboot

1

Puede utilizar propiedades:

Object.defineProperty MDN documentation

Ejemplo:

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 
Cuestiones relacionadas