Вопрос был отправлен давным-давно, много ответов периодически объединяют цель, и производит ненужную трату ресурсов, если цель неизменна. Кроме того, большинство ответов не блокирует программу при ожидании изменений как требуется исходным сообщением.
Мы можем теперь применить решение, которое чисто событийно-ориентировано.
решение использует onClick событие для поставки события, инициированного изменением значения.
решение может быть выполнено на современных браузерах, которые поддерживают Обещание и асинхронный/ждущий. Если Вы используете Node.js, рассматриваете EventEmitter как лучшее решение.
<!-- 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>
Супер датированный, но конечно хорошие способы разместить это. Просто описал это для проекта и полагал, что я совместно использую. Подобный некоторым из других, варьировался по стилю.
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;
JavaScript является одним из худшего program\scripting языка когда-либо!
"Ожидают", кажется, невозможен в JavaScript! (Да, как в реальной жизни, иногда ожидание является наилучшим вариантом!)
я попробовал, "в то время как" цикл и "Рекурсия" (вызовы функции сама неоднократно до...), но JavaScript отказывается работать так или иначе! (Это невероятно, но так или иначе, см. коды ниже:)
цикл с условием продолжения:
<!DOCTYPE html>
<script>
var Continue = "no";
setTimeout(function(){Continue = "yes";}, 5000); //after 5 seconds, "Continue" is changed to "yes"
while(Continue === 'no'){}; //"while" loop will stop when "Continue" is changed to "yes" 5 seconds later
//the problem here is that "while" loop prevents the "setTimeout()" to change "Continue" to "yes" 5 seconds later
//worse, the "while" loop will freeze the entire browser for a brief time until you click the "stop" script execution button
</script>
Рекурсия:
<!DOCTYPE html>
1234
<script>
function Wait_If(v,c){
if (window[v] === c){Wait_If(v,c)};
};
Continue_Code = "no"
setTimeout(function(){Continue_Code = "yes";}, 5000); //after 5 seconds, "Continue_Code" is changed to "yes"
Wait_If('Continue_Code', 'no');
//the problem here, the javascript console trows the "too much recursion" error, because "Wait_If()" function calls itself repeatedly!
document.write('<br>5678'); //this line will not be executed because of the "too much recursion" error above!
</script>
С другой стороны, можно сделать функцию, которая выполняет задачи на основе значения ее "Статических" переменных, примера ниже:
<!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>
То, что работало на меня (я посмотрел повсеместно и закончил тем, что использовал чей-то jsfiddler / очень немного изменение, это - работало приятно), должно было установить ту переменную на объект с методом считывания и методом set, и метод set инициировал функцию, которая ожидает переменного изменения.
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();
};
};