Extending Promises in ES6
Asked Answered
M

1

23

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?

Misrule answered 29/3, 2015 at 19:6 Comment(6)
That should work imo. My guess is that neither of the transpilers supports this.Non
New Viewers Note - the code example in this question should now compile and work in Babel.Trader
@BenjaminGruenbaum I am using Babel + ES2015 preset and I am still getting TypeError: #<ExtendedPromise> is not a promise when I call the constructor new ExtendedPromise(res => {}). Is there any other trick to this?Assai
@Assai probably because you're not using the polyfill and/or are on a browser which offers native promises.Trader
@BenjaminGruenbaum Thank you!Assai
@BenjaminGruenbaum The polyfill is needed even if the browser natively supports promises?Annieannihilate
T
21

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.

Trader answered 30/3, 2015 at 16:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.