views:

178

answers:

5

I want to force a JavaScript program to wait in some particular points of its execution until a variable has changed. Is there a way to do it? I have already found an extension that is called "narrative JavaScript" that force the program to wait until an event to happen. Is there a way to create a new event, a "variable change event" for example that behaves like onclick event..

Thank you, Thanasis

A: 

No you would have to create your own solution. Like using the Observer design pattern or something.

If you have no control over the variable or who is using it, I'm afraid you're doomed. EDIT: Or use Skilldrick's solution!

Mike

Mike Gleason jr Couturier
+3  A: 

a quick and easy solution goes like this:

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();
aularon
Yes, but you must wait half of a second in worst case to be informed hat value is changed, and your example only works with bool.
Cipi
edited now, it checks every 50ms and works for non-bools. it's as I said the quick and easy way to do that, follow this link: http://stackoverflow.com/questions/1029241/javascript-object-watch-for-all-browsers (posted already by @mplungjan) for a more in-depth problems-proof solution.
aularon
I think you meant `something===something_cachedValue`. Then it works: http://jsfiddle.net/pEnYC/
Skilldrick
@Skilldrick, yes I meant that, I fixed it. Thanks for the correction : )
aularon
Thank you all for your answers! But in all of the solutions the program will not block! It will continue its execution normally, and if the variable change during the execution then a callback will be called. But, what I want to do is to force the program to block its execution until the variable change (by calling a function), and then continue from this point where it got blocked! Any ideas?
Thanasis Petsas
A: 

I would recommend a wrapper that will handle value being changed. For example you can have JavaScript function, like this:

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


}

And then you can make an object out of it that will hold value that you want to monitor, and also a function that will be called when the value gets changed. For example, if you want to be alerted when the value changes, and initial value is 10, you would write code like this:

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

Handler function(){alert("Value changed!");} will be called (if you look at the code) when SetValue() is called.

You can get value like so:

alert(myVar.GetValue());

You can set value like so:

myVar.SetValue(12);

And immediately after, an alert will be shown on the screen. See how it works: http://jsfiddle.net/cDJsB/

Cipi
Thank you for the answer, but it isn't exactly what I want. Look my comment to aularon please!
Thanasis Petsas
+2  A: 

JavaScript interpreters are single threaded, so a variable can never change, when the code is waiting in some other code that does not change the variable.

In my opinion it would be the best solution to wrap the variable in some kind of object that has a getter and setter function. You can then register a callback function in the object that is called when the setter function of the object is called. You can then use the getter function in the callback to retrieve the current value:

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

This could be easily used like this:

<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>
Reboot
Probably the best solution if you've got control over the original variable.
Skilldrick
You are not copying my answer at all dude... xD
Cipi
Thank you for the answer, but it isn't exactly what I want. Look my comment to aularon please!
Thanasis Petsas
As I explained JavaScript interpreters are single threaded. You can not block the thread and make it wait for some other thread to change a variable, because there is no other thread that can change a variable. No JavaScript event handler can be executed while another is already executing.
Reboot