通过承诺返回ES6代理时堆栈溢出

我试图拦截ES6代理上的方法调用,以便能够使用从代理获得的信息在两者之间进行操作。 现在在我的情况下,在创build和从某种工厂返回代理之前,有相当多的东西正在进行。 因为所有这些东西,我决定将先决条件包装到promise函数中,这样我就可以将代理创build权链接到它上面,并通过promise链返回结果代理。 以下是重现问题的代码:

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问题中提出了这个问题,你可以在这里find以前的对话: https : //github.com/nodejs/node/issues/8082也许它可以帮助别人帮我;)

你的问题是你的代理总是返回一个函数访问任何属性,包括then 。 这将使承诺的实现把它看作是一个可行的,试图解决它 – 你的代码出现了可怕的错误。 但是你应该解决问题的根源:

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

这是一个蓝色的射门,但你可能正在寻找

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