【问题标题】:stack overflow when returning an ES6 proxy through a promise通过承诺返回 ES6 代理时堆栈溢出
【发布时间】:2016-08-15 07:32:27
【问题描述】:

我正在尝试拦截 ES6 代理上的方法调用,以便能够使用从代理获得的信息在两者之间进行处理。现在就我而言,在从某种工厂创建和返回代理之前,有很多事情要做。由于所有这些东西,我决定将先决条件包装到一个承诺函数中,以便我可以将代理创建直接链接到它并通过承诺链返回生成的代理。这是重现问题的代码:

proxy_factory.min.js

'use strict';

// require('harmony-reflect');

class ProxyFactory {

  create(options) {

    const self = this;

    const handler = {

      get(target, propertyKey, receiver) {

        if (propertyKey === 'then') {

          return function proxyPromiseWrapper(thenCallback) {
            const innerProxy = self.create(options);
            return thenCallback(innerProxy);
          };
        }

        return function resourceFunctionProxy() {

          const callContext = {
            target: target,
            method: propertyKey,
            args: arguments,
            thisContext: this
          };

          const resourceInstanceMethod = Reflect.get(options.originalObject, callContext.method);
          return resourceInstanceMethod.apply(callContext.thisContext, callContext.arguments);

        };
      }
    };

    return new Proxy(options.originalObject, handler);
  }

}

module.exports = ProxyFactory;

test.js

'use strict';

const Promise = require('bluebird');
const ProxyFactory = require('./proxy_factory.min.js');

const proxyFactory = new ProxyFactory();

function createProxyWithPromise() {

  const TestClass = class {
    doSomething() {
      return Promise.resolve('promise return value');
    }
  };

  const options = {
    originalObject: new TestClass()
  };

  return Promise.resolve()
    .then(() => {
      return proxyFactory.create(options);
    });
}

function test() {

  createProxyWithPromise()
    .then((proxy) => {

      const result = proxy.doSomething();

      console.log(result); // should output 'promisereturnvalue'
    });
}

test();

在代理上调用 doSomething() 之前,会一遍又一遍地调用 then() 函数,从而导致堆栈溢出。 我已经在 node.js github 问题中问过这个问题,你可以在这里找到之前的对话:https://github.com/nodejs/node/issues/8082 也许它可以帮助某人帮助我;)

【问题讨论】:

  • 嗯,是的,proxyPromiseWrapper 将立即使用另一个 thenable 调用回调,而不是等待结果。我不知道你想做什么,也不知道为什么要在那里特别对待承诺。
  • 你的代理很奇怪。无论什么属性,它总是返回一个函数。
  • 您不应该将ProxyFactory 设为一个类。它不持有任何状态,所以不要创建它的实例。只需导出createProxy(option) 工厂函数即可。
  • 是的 proxyPromiseWrapper 是我试图处理“干扰”我的拦截的承诺。我的问题是我必须通过承诺链返回代理,因此只能在代理内部调用then。我想要实现的是假装 then 没有在我的代理上调用,这样我就可以获得在我通过承诺链返回代理后发生的实际方法调用。我用它做了一堂课,因为当一个电话被拦截时会有更多的事情发生。
  • 我想你需要做的就是return undefined。如果您的代理不包含承诺,则它不应该是 thenable。

标签: javascript node.js proxy ecmascript-6 es6-promise


【解决方案1】:

你的问题是你的代理总是返回一个函数来访问任何属性,包括then。这将使 Promise 实现将其视为一个 thenable,试图解决它 - 你的代码出现了可怕的错误。但是你应该解决问题的根源:

get (target, propertyKey, receiver) {
    if (!(propertyKey in target))
        return undefined;
    else if (typeof target[propertyKey] != "function")
        return …;
    else
        return function resourceFunctionProxy() {
            …

【讨论】:

  • 这成功了,我也不知道检查对象是否有键的简短语法。现在我想我也理解了这个问题。谢谢你的帮助!这让我已经睡了不止一晚了^^
【解决方案2】:

这是一个晴天霹雳,但您可能正在寻找

return function proxyPromiseWrapper(thenCallback) {
    return options.originalObject.then(function(result) {
        const resultOptions = Object.assign({}, options, {target: result});
        const innerProxy = self.create(resultOptions);
        return thenCallback(innerProxy);
    });
};

【讨论】:

    猜你喜欢
    • 2018-10-29
    • 2015-03-14
    • 1970-01-01
    • 2019-05-18
    • 1970-01-01
    • 2020-06-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多