【问题标题】:Proxy get handler called on evaluation of proxy在评估代理时调用代理获取处理程序
【发布时间】:2017-10-25 08:39:25
【问题描述】:

我定义了一个代理如下:

const o1 = {
      ready: false
    };

setTimeout(() => {
  o1.ready = true;
}, 1000000000);

const handler = {
  get(target, propKey, receiver) {
    if (target.ready == false) {
      throw new Error('not ready');
    } else {
      return 'ready'
    }
  }
};

const proxy = new Proxy(o1, handler);

proxy; // raises 'not ready'

评估proxy 会引发错误“未准备好”,即使它不是属性访问。在评估对代理的引用时,如何防止引发错误?这会在没有赋值的情况下导致错误。

【问题讨论】:

  • 你看到这个是什么环境?在 chrome 上测试,它按预期工作,编辑:刚刚在节点中复制
  • 节点 v8.7.0。我在 chrome 上也没有错误:/
  • 在 github 上创建了一个问题,将更新详细信息
  • hmmmm...我没有得到readynot ready。代理的 get 处理程序用于访问代理本身的属性。 proxy.ready 将触发 not ready。但是,我看不出你的代码是如何触发任何事情的......

标签: javascript node.js proxy


【解决方案1】:

好像和这个bug有关:https://github.com/nodejs/node/issues/10731

我发现的最佳解决方法是专门忽略节点检查:

const handler = {
  get(target, propKey, receiver) {
    if (propKey != util.inspect.custom && 
        propKey != 'inspect' && 
        propKey != Symbol.toStringTag){
      if (target.ready == false) {
        throw new Error('not ready');
      } else {
        return 'ready'
      }
    }
  }
};

或者,如果您知道您关心的键列表,那么只需检查这些而不是排除。

【讨论】:

  • 它寻找“检查”是奇怪的部分:/。谢谢!
【解决方案2】:

显然,您正在 REPL 中对此进行评估,其中最终的 proxy; 语句生成代码的结果值并记录到控制台。记录它将访问属性,这是预期的。

但是,您确实不应该在这里使用代理。代理应该单独处理不同的属性,但您的似乎只关心 ready 属性。更简单的 getter 会更合适:

const o1 = {
  ready: false
};
setTimeout(() => {
  o1.ready = true;
}, 1000000000);

const res = { // instead of the `proxy` object
  get ready() {
    if (o1.ready == false) {
      throw new Error('not ready');
    } else {
      return 'ready'
    }
  }
};

res.ready // either throws or yields the string "ready"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-07-06
    • 2012-08-19
    • 2017-03-17
    • 1970-01-01
    • 2015-09-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多