【问题标题】:Listen to js variable change监听js变量变化
【发布时间】:2021-01-28 13:14:14
【问题描述】:

假设在 place 2

中有一个代码
var place2IsReady = true;

place 1我需要实现以下逻辑:

Once place2IsReady value was changed (to true) then display alert('ready!');

注意事项:

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

解决方案 1

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

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

附:我只需要跟踪place2IsReady第一个可能的变化

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

【问题讨论】:

  • 你在使用一些框架吗?
  • 变量不做任何形式的变化通知。您要么必须不断轮询并检查变量是否已更改,要么实际上使用某些模式或库来跟踪更改。
  • @distante 我更喜欢的答案:不。在某些地方是 JS + TS + jQuery。 Vanilla JS 解决方案更可取。
  • "place2IsReady" 可以是对象而不是布尔值?
  • 不确定您到底在寻找什么,但您可以使用javascript.info/property-accessors getter/setter 来执行 setter 调用的相关操作。

标签: javascript typescript scope window


【解决方案1】:

您可以使用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();
}

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

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

或者也许使用Proxy(带有设置陷阱)对你有用

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);

【讨论】:

  • 谢谢。你能解释一下为什么 place2IsReady = true; place2IsReady = 假; place2IsReady = true;不显示第二个警报?
  • 如果我明白你的意思,我可以
  • @Kooilnc,知道了,谢谢,只执行了一次。
【解决方案2】:

假设您可以将 place2IsReady 替换为对象:

place2IsReady = {
  state: false,
  set ready(value) {
      this.state = value
      state && place_1_call()
  },
  get ready() { 
    return state
  }
}

place_1_call = () => {
  alert('ready')
}

place2IsReady.ready = true

【讨论】:

    猜你喜欢
    • 2013-01-05
    • 2010-12-18
    • 1970-01-01
    • 1970-01-01
    • 2011-04-07
    • 2013-07-22
    • 1970-01-01
    相关资源
    最近更新 更多