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..
-
1i think the best way is to use rxjs library and use an observable as your variable. – Az264 Nov 30 '19 at 13:11
10 Answers
Edit 2018: Please look into Object getters and setters and Proxies. Old answer below:
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();

- 11,042
- 3
- 36
- 41
-
1edited 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 Sep 03 '10 at 13:37
-
I think you meant `something===something_cachedValue`. Then it works: http://jsfiddle.net/pEnYC/ – Skilldrick Sep 03 '10 at 13:45
-
@Skilldrick, yes I meant that, I fixed it. Thanks for the correction : ) – aularon Sep 03 '10 at 13:48
-
2Thank 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 Sep 09 '10 at 12:13
-
Do like this guy does, make the variable trigger the method you want. That way the method won't be waiting for anything, it will be called when the variable is ready. http://jsfiddle.net/cDJsB/ – JakeJ Jul 30 '19 at 23:37
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>

- 1,716
- 2
- 14
- 27
-
2Probably the best solution if you've got control over the original variable. – Skilldrick Sep 03 '10 at 13:58
-
Thank you for the answer, but it isn't exactly what I want. Look my comment to aularon please! – Thanasis Petsas Sep 09 '10 at 12:16
-
1As 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 Sep 10 '10 at 22:42
-
It works as described. Thanks!!! This was very helpful. I needed to take out the extra right parenthesis in function Wrapper(callback)). – AggieMan Jan 24 '17 at 18:24
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/

- 11,055
- 9
- 47
- 60
-
Thank you for the answer, but it isn't exactly what I want. Look my comment to aularon please! – Thanasis Petsas Sep 09 '10 at 12:16
The question was posted long time ago, many answers pool the target periodically and produces unnecessary waste of resources if the target is unchanged. In addition, most answers do not block the program while waiting for changes as required by the original post.
We can now apply a solution that is purely event-driven.
The solution uses onClick event to deliver event triggered by value change.
The solution can be run on modern browsers that support Promise and async/await. If you are using Node.js, consider EventEmitter as a better solution.
<!-- This div is the trick. -->
<div id="trick" onclick="onTrickClick()" />
<!-- Someone else change the value you monitored. In this case, the person will click this button. -->
<button onclick="changeValue()">Change value</button>
<script>
// targetObj.x is the value you want to monitor.
const targetObj = {
_x: 0,
get x() {
return this._x;
},
set x(value) {
this._x = value;
// The following line tells your code targetObj.x has been changed.
document.getElementById('trick').click();
}
};
// Someone else click the button above and change targetObj.x.
function changeValue() {
targetObj.x = targetObj.x + 1;
}
// This is called by the trick div. We fill the details later.
let onTrickClick = function () { };
// Use Promise to help you "wait". This function is called in your code.
function waitForChange() {
return new Promise(resolve => {
onTrickClick = function () {
resolve();
}
});
}
// Your main code (must be in an async function).
(async () => {
while (true) { // The loop is not for pooling. It receives the change event passively.
await waitForChange(); // Wait until targetObj.x has been changed.
alert(targetObj.x); // Show the dialog only when targetObj.x is changed.
await new Promise(resolve => setTimeout(resolve, 0)); // Making the dialog to show properly. You will not need this line in your code.
}
})();
</script>

- 31
- 4
What worked for me (I looked all over the place and ended up using someone's jsfiddler / very slightly modifying it - worked nicely) was to set that variable to an object with a getter and setter, and the setter triggers the function that is waiting for variable change.
var myVariableImWaitingOn = function (methodNameToTriggerWhenChanged){
triggerVar = this;
triggerVar.val = '';
triggerVar.onChange = methodNameToTriggerWhenChanged;
this.SetValue(value){
if (value != 'undefined' && value != ''){
triggerVar.val = value; //modify this according to what you're passing in -
//like a loop if an array that's only available for a short time, etc
triggerVar.onChange(); //could also pass the val to the waiting function here
//or the waiting function can just call myVariableImWaitingOn.GetValue()
}
};
this.GetValue(){
return triggerVar.val();
};
};

- 2,361
- 5
- 23
- 35
You can use properties:
Object.defineProperty MDN documentation
Example:
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

- 2,826
- 1
- 29
- 31

- 17,828
- 6
- 117
- 94
Example for a more functional promise (async/await) based approach:
var delay = require('delay');
var obj = {
k: null
};
function notAwaitable() {
return obj.k;
}
async function waitFor(f) {
let r = f();
while (!r) {
console.log('Not yet, waiting more');
await delay(1000);
r = f();
}
return r;
}
(async function() {
await delay(5000);
obj.k = 42;
})();
(async function() {
let result = await waitFor(notAwaitable);
console.log(result);
})();

- 919
- 1
- 13
- 28
Super dated, but certainly good ways to accomodate this. Just wrote this up for a project and figured I'd share. Similar to some of the others, varied in style.
var ObjectListener = function(prop, value) {
if (value === undefined) value = null;
var obj = {};
obj.internal = value;
obj.watcher = (function(x) {});
obj.emit = function(fn) {
obj.watch = fn;
};
var setter = {};
setter.enumerable = true;
setter.configurable = true;
setter.set = function(x) {
obj.internal = x;
obj.watcher(x);
};
var getter = {};
getter.enumerable = true;
getter.configurable = true;
getter.get = function() {
return obj.internal;
};
return (obj,
Object.defineProperty(obj, prop, setter),
Object.defineProperty(obj, prop, getter),
obj.emit, obj);
};
user._licenseXYZ = ObjectListener(testProp);
user._licenseXYZ.emit(testLog);
function testLog() {
return function() {
return console.log([
'user._licenseXYZ.testProp was updated to ', value
].join('');
};
}
user._licenseXYZ.testProp = 123;

- 3,052
- 3
- 24
- 29
Alternatively, you can make a function that executes tasks based on the value of its "Static" variables, example below:
<!DOCTYPE html>
<div id="Time_Box"> Time </div>
<button type="button" onclick='Update_Time("on")'>Update Time On</button>
<button type="button" onclick='Update_Time("off")'>Update Time Off</button>
<script>
var Update_Time = (function () { //_____________________________________________________________
var Static = []; //"var" declares "Static" variable as static object in this function
return function (Option) {
var Local = []; //"var" declares "Local" variable as local object in this function
if (typeof Option === 'string'){Static.Update = Option};
if (Static.Update === "on"){
document.getElementById("Time_Box").innerText = Date();
setTimeout(function(){Update_Time()}, 1000); //update every 1 seconds
};
};
})();
Update_Time('on'); //turns on time update
</script>

- 71
- 1
- 7
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

- 9,018
- 4
- 40
- 59
-
1@JakeJ that's what I'm saying, you would have to create your own solution. – Mike Gleason jr Couturier Jul 31 '19 at 11:00