promiseecmascript-6traceures6-promisebabeljs

Extending Promises in ES6


I am trying to extend Promise:

class PersistedPromise extends Promise { }

Then call the static resolve on the derived class to directly create a resolved promise:

PersistedPromise.resolve(1)

In traceur, this yields:

ModuleEvaluationError: #<PersistedPromise> is not a promise
    at new PersistedPromise (~rtm/gen/promise.js:6:57)
    at Function.resolve (native)

In Babel (run as babel-node --experimental promise.js) it results in:

    Promise.apply(this, arguments);
            ^
TypeError: [object Object] is not a promise
    at new PersistedPromise (~rtm/gen/promise.js:1:23)
    at Function.resolve (native)
    ...

I was depending on this:

All static methods of Promise support subclassing: they create new instances via their receiver (think: new this(...)) and also access other static methods via it (this.resolve(...) versus Promise.resolve(...)).

from http://www.2ality.com/2014/10/es6-promises-api.html.

It appears that node checks the this on calls such as Promise.resolve.call(this, val) for being a Promise, rather than (correctly?) Promise or a derived class thereof (v0.12.0).

Is the above no longer operative, or did not make into the spec, or just not implemented by traceur and/or node?


Solution

  • Is the above no longer operative, or did not make into the spec, or just not implemented by traceur and/or node?

    ES6 promises in the spec support subclassing. That is, you will eventually be able to subclass promises the way you just did. This is by design.

    That said, none of the browsers currently follow that spec correctly in this regard - as far as I know only the ES6-promise shim, Babel (core-js) and RSVP follow ES6 semantics with regards to subclassing correctly. Support in browsers is eventually coming but it's not there yet. Hold tight.

    Here is a list of currently supporting implementations.