如何在JavaScript es6中代理一个Promise

9

我正在尝试在原生Firefox中代理一个Promise(并使用Babel)。

var prom = new Promise(function(resolve, reject){resolve(42)});
var promProxy = new Proxy(prom, {});
promProxy.then(function(response){console.log(response)});

这段代码无法正常工作,会出现“TypeError: 'then' called on an object that does not implement interface Promise.”的错误提示。


你为什么要尝试这个?实际上,代理并不是原生的 Promise 对象。也许你正在寻找子类化? - Bergi
2个回答

10
你需要让你的处理程序实现get()陷阱并返回 prom.then 绑定版本。
var prom = new Promise(function(resolve, reject){resolve(42)});
var promProxy = new Proxy(prom, {
  get: function(target, prop) {
    if (prop === 'then') {
      return target.then.bind(target);
    }
  }
});
promProxy.then(function(response){console.log(response)});

请注意,如果您只想代理所有访问器,get函数应该像这样:

var promProxy = new Proxy(prom, {
  get: function(target, prop) {
    var value = target[prop];
    return typeof value == 'function' ? value.bind(target) : value;
  }
});

bind 将确保在处理原生对象,如 Promise 或 console 时不会错误地调用该函数。

编辑:在某些情况下,浏览器/ node 可能会有过时的代理版本,在这种情况下,您需要使用harmony-reflect将其更新到最新版本。


6

嗯,这个问题是关于如何代理一个Promise。我来到这里寻找如何将代理包装成Promise - 或更准确地说,如何解决代理问题。我猜其他人也可能会来到这里,所以我会把这个问题在这里发布,以防万一。

我已经有了一个很好的工作代理对象,然后我试图将其包装在一个Promise中:

var p = new Promise(function(resolve, reject) {
  var proxy = get_my_proxy();
  resolve(proxy);
});

并且你知道吗,这个拗口的 resolve 方法要求我的代理提供一个名为 then 的属性(这是我的代理逻辑意料之外的),导致它抛出异常。根据您的代理用途不同,这可能不是最理想的解决方法,但以下是我如何解决这个问题的方法(恰好与我的问题相反,因此解决方案也是相反的)- 通过返回null以表示我没有传递给resolve()一个Promise(又称Thenable)。
get: function(target, prop) {
  if (prop === 'then') return null; // I'm not a Thenable
  // ...the rest of my logic
}

刚遇到这个问题,感谢回答。 - Thiatt
这个救了我的一命。 - Rizky Ramadhan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接