【问题标题】:How can I know if there are any references to a given instance?我如何知道是否有对给定实例的引用?
【发布时间】:2021-07-29 11:51:18
【问题描述】:

我正在构建一个队列,如果没有对该队列实例的引用,我想避免执行任何任务。

我用WeakRef 尝试了一些东西,但可能永远不会成功。

const queue = () => {
  const enqueue = () => {
    console.log("enqueue");
    setTimeout(() => {
      if (instanceRef.deref()) {
        console.log("the queue is still referenced so perform task");
      }
    });
  };

  const instance = { enqueue };
  const instanceRef = new WeakRef(instance);
  return instance;
};
b = queue();
b.enqueue();
b = null;
console.log("b is set to null so there are no references to the instance");

如果队列仍然存在但不太优雅,则另一种方法是检查任务。

【问题讨论】:

  • 可能永远不会工作” - 为什么不呢?当然,这种方法会奏效,您永远不会等待足够长的时间让 instance 真正被垃圾收集。
  • 好吧,我猜永远不会可靠地工作。你预计要等多久?我等了 1 分钟仍然被引用。
  • 如果它决定被垃圾收集......例如现在,调试器可能仍然在闭包内使用instance ref,即使它没有在函数内部使用关闭。
  • 如果您在超时发生前进入开发工具 Memory 面板并单击 Collect Garbage 按钮,您的代码实际上可以正常工作。如果你想让它自己发生,你需要给引擎施加一些内存压力。除非你给它一个理由,否则垃圾收集器不会回收内存——仅仅等待是不够的。即便如此,您的代码也绝不能依赖于被垃圾收集的东西。如果您希望任务执行具有确定性,则需要自己进行引用计数。
  • 非常感谢Bergi!

标签: javascript weak-references


【解决方案1】:

不能依靠WeakRef#deref() 来知道是否仍然存在对目标对象的(强)引用。它仅指示垃圾收集器是否已销毁对象并回收其内存。这可能会在很久以后发生,也可能永远不会发生。

【讨论】:

    【解决方案2】:

    你想要的有点奇怪。您想通过将 null 分配给先前已启动超时功能的变量来神奇地停止超时功能。

    您更想要的是有一个停止超时功能的方法。调用 setTimeout 返回一个处理程序。存储此处理程序并调用内置方法

    clearTimeout(handler)

    【讨论】:

    • 我认为您误解了这个问题。超时只是为了说明一点。
    • 如果没有超时,无论如何都不会执行任何函数。
    猜你喜欢
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-03
    • 1970-01-01
    相关资源
    最近更新 更多