监听js变量变化

Har*_*iec 8 javascript scope window typescript

假设有一个代码2

var place2IsReady = true;
Run Code Online (Sandbox Code Playgroud)

位置 1中,我需要实现以下逻辑:

Once place2IsReady value was changed (to true) then display alert('ready!');
Run Code Online (Sandbox Code Playgroud)

笔记:

  • place2IsReady变量在地点 1的范围内不可用。
  • 位置 1的代码在位置 2执行之前执行(或者存在竞争条件)。

解决方案1

我相信我可以使用 window.place2IsReady 代替,并在位置 1 中使用 setTimeout/setInterval 直到我得到window.place2IsReady === true

还有更好的选择吗?使用监听器?关于变量的变化?

PS我只需要跟踪place2IsReady的第一个可能的更改。

有没有更好的办法?谢谢。

Koo*_*Inc 5

setTimeout您可以使用以下命令创建变量更改的侦听器:

let place2IsReady = false;

setReadyListener();

// testing wait 2 seconds to set place2IsReady to true
// so: an alert should occur after 2 seconds
setTimeout(() => place2IsReady = true, 2000);

function setReadyListener() {
  const readyListener = () => {
    if (place2IsReady) {
      return alert("Ready!");
    }
    return setTimeout(readyListener, 250);
  };
  readyListener();
}
Run Code Online (Sandbox Code Playgroud)

更通用的监听器“工厂”可能是:

let place2IsReady = false;
let fromObj = {
  place2IsReady: "busy",
  done() { this.place2IsReady = "done"; },
};
const listen = changeListenerFactory();

listen(
  () => place2IsReady, 
  () => console.log("place2IsReady") );
listen(
  () => fromObj.place2IsReady === "done", 
  () => console.log("formObj.place2IsReady done!") );
  
console.log("Listening...");

// test change variables with listeners
setTimeout(() => place2IsReady = true, 1000);
setTimeout(() => fromObj.done(), 3000);

function changeListenerFactory() {
  const readyListener = (condition, callback, delay) => {
    if (!condition || typeof condition !== "function") { return true; }
    if (condition()) {
      return callback();
    }
    setTimeout(() => readyListener(condition, callback, delay), delay);
  };
  
  return (condition, callback = () => {}, delay = 250) => 
    readyListener(condition, callback, delay);
}
Run Code Online (Sandbox Code Playgroud)

或者也许使用代理(带有设置陷阱)适合您

const readyState = new Proxy({ ready: false }, { 
  set (target, prop, val) {
    console.log(`readyState.ready changed from ${target[prop]} to ${val}`);
    target[prop] = val;
  }
});

console.log("Waiting for changes ...");
setTimeout(() => readyState.ready = true, 2000);
Run Code Online (Sandbox Code Playgroud)