stack overflow when returning an ES6 proxy through a promise

断了今生、忘了曾经 提交于 2019-12-08 08:10:48

问题


I'm trying to intercept a method call on a ES6 proxy to be able to do stuff in between with the information I get from the proxy. Now in my case there is quite some stuff going on before creating and returning the proxy from some kind of factory. Because of all this stuff I decided to wrap the prerequisites into a promise-function so that I can chain the proxy creation right onto it and return the resulting proxy through the promise chain. Here's the code to reproduce the problem:

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

Before doSomething() is called on the proxy the then()-function is called over and over again, resulting in a stack overflow. I already asked this question in the node.js github issues and you can find the previous conversation here: https://github.com/nodejs/node/issues/8082 Maybe it helps someone helping me ;)


回答1:


Your problem is that your proxy always returns a function for accesses on any property, including then. That will make promises implementations treat it as a thenable, trying to to resolve it - where your code went horribly wrong. But you should fix the root of the issue:

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



回答2:


It's a shot in the blue, but you might be looking for

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


来源:https://stackoverflow.com/questions/38951001/stack-overflow-when-returning-an-es6-proxy-through-a-promise

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!