2010-09-03 12 views
45

Chcę wymusić program JavaScript, aby poczekał w niektórych określonych punktach jego wykonania, dopóki zmienna się nie zmieni. Czy jest jakiś sposób na zrobienie tego? Znalazłem już rozszerzenie o nazwie "narracyjny JavaScript", które zmusza program do oczekiwania na zdarzenie. Czy istnieje sposób na stworzenie nowego zdarzenia, na przykład "zdarzenie zmiany zmiennej", które zachowuje się jak zdarzenie onclick ..Jak mogę sprawić, aby program czekał na zmianę zmiennej w javascript?

Odpowiedz

0

Nie trzeba tworzyć własnych rozwiązań. Podobnie jak przy użyciu wzorca obserwacyjnego Observera lub czegoś podobnego.

Jeśli nie masz kontroli nad zmienną lub kto jej używa, obawiam się, że jesteś zgubiony. EDYCJA: Lub użyj rozwiązania Skilldrick's!

Mike

76

szybkie i łatwe rozwiązanie idzie tak:

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

edytowane teraz, sprawdza co 50ms i działa dla non-bools.tak jak powiedziałem, szybki i łatwy sposób to zrobić, podążaj za tym linkiem: http://stackoverflow.com/questions/1029241/javascript-object-watch-for-all-browsers (wysłany już przez @mplungjan), aby uzyskać więcej dogłębne rozwiązanie problemu. – aularon

+0

Myślę, że chodziło Ci o "coś === coś_popieranego". Wtedy to działa: http://jsfiddle.net/pEnYC/ – Skilldrick

+0

@Skilldrick, tak miałem na myśli to, naprawiłem to. Dzięki za korektę:) – aularon

5

Polecam owijkę, która będzie obsługiwać wartość ulega zmianie. Na przykład można mieć funkcji JavaScript, podobnie jak to:

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


} 

a następnie można utworzyć obiekt z niego, że będą trzymać wartości, które chcesz monitorować, a także funkcję, która będzie wywoływana, gdy wartość dostaje zmienione. Na przykład, jeśli chcesz być powiadomiony, gdy zmienia się wartość, a wartość początkowa wynosi 10, należy napisać kod tak:

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

Handler function(){alert("Value changed!");} będzie nazwane (jeśli spojrzeć na kod), gdy SetValue() jest nazywa.

można uzyskać wartość tak:

alert(myVar.GetValue()); 

Można ustawić wartość tak:

myVar.SetValue(12); 

i bezpośrednio po, pokazany zostanie alert na ekranie. Zobacz, jak to działa: http://jsfiddle.net/cDJsB/

+0

Dziękuję za odpowiedź, ale nie jest to dokładnie to, czego chcę. Popatrz na mój komentarz na aularon! –

15

Tłumacze JavaScript są jednowątkowe, więc zmienna nigdy się nie zmienia, gdy kod czeka w innym kodzie, który nie zmienia zmiennej.

Moim zdaniem byłoby najlepszym rozwiązaniem do zawijania zmiennej w jakiś obiekt, który ma funkcję getter i setter. Następnie można zarejestrować funkcję zwrotną w obiekcie wywoływanym, gdy wywoływana jest funkcja ustawiająca obiektu. Następnie można użyć funkcji getter w zwrotnego aby pobrać aktualną wartość:

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

To może być łatwo wykorzystane tak:

<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

Prawdopodobnie najlepsze rozwiązanie, jeśli masz kontrolę nad oryginalną zmienną. – Skilldrick

+0

Dziękuję za odpowiedź, ale nie jest to dokładnie to, czego chcę. Popatrz na mój komentarz na aularon! –

+1

Jak wyjaśniłem, tłumacze JavaScript są jednowątkowe. Nie można zablokować wątku i sprawić, że będzie oczekiwał na zmianę innego wątku przez inny wątek, ponieważ nie ma innego wątku, który mógłby zmienić zmienną. Żadna procedura obsługi zdarzeń JavaScript nie może zostać wykonana, gdy inna już jest wykonywana. – Reboot

1

Można użyć właściwości:

Object.defineProperty MDN documentation

Przykład:

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 
Powiązane problemy