扩展内置的JavaScript承诺

Eve*_*ert 6 javascript promise

我正在尝试使用新方法扩展javascript承诺.在这种情况下调用这个新方法foo,它实际上是这样的:

Promise.foo = function(arg) {
  return this.then( function(result) {
    return result.foo(arg);
  });
};
Run Code Online (Sandbox Code Playgroud)

简而言之,foo()函数是等待promise解析然后在结果上调用foo()的快捷方式.

这个函数的本质是它可以被链接,就像then()可以一样.

myPromise.foo(a).foo(b).foo(c);
Run Code Online (Sandbox Code Playgroud)

我觉得这应该是可能的,但我不确定正确的道路是什么.

这就是我尝试过的:

var FooPromise = function() {
   Promise.apply(this, arguments);
}

FooPromise.prototype = Object.create(Promise.prototype);
FooPromise.foo = function(arg) {
  return this.then( function(result) {
    return result.foo(arg);
  });
};
Run Code Online (Sandbox Code Playgroud)

测试一下:

var test = new FooPromise(function(res, rej) {
   res('bla');
});
Run Code Online (Sandbox Code Playgroud)

在Firefox中,这给了我:

TypeError: calling a builtin Promise constructor without new is forbidden
Run Code Online (Sandbox Code Playgroud)

在节点中:

TypeError: #<Promise> is not a promise
Run Code Online (Sandbox Code Playgroud)

这只是javascript的限制,还是有办法解决这个问题?

小智 9

ES6方式:

class FooPromise extends Promise {
    constructor(executor) {
        super(executor);
    }
}

var fooPromise = new FooPromise((resolve,reject)=>{
   resolve(null);
});
Run Code Online (Sandbox Code Playgroud)


Eve*_*ert 3

经过更多研究,我找到了以下解决方案。无需扩展内置 Promise。您真正需要的是确保您的对象then正确实现(又名 Promise/A+/thenable)。

function FooPromise(executor) {

  this.innerPromise = new Promise(executor);

}

FooPromise.prototype = {

 then: function(onFulfilled, onRejected) {

    return new FooPromise(function(res, rej) {

       this.innerPromise.then(res, rej);

    });

  },

  foo: function() {

    return this.then(function(val) {

      return val.foo();

    });

  }

}
Run Code Online (Sandbox Code Playgroud)

这在 ES5 环境中运行良好,与其他 Promise 甚至 async/await(如果可用)完美配合。

在这个开源库中成功实现了这种模式。