Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Are DOM Promises intended to be inherited from in user code? #71

Open
juandopazo opened this issue Jul 18, 2013 · 10 comments
Open

Are DOM Promises intended to be inherited from in user code? #71

juandopazo opened this issue Jul 18, 2013 · 10 comments

Comments

@juandopazo
Copy link

I just tried the implementation in Chromium 30 and Firefox Nightly and both throw an error when trying to use prototype delegation with them.

Chromium throws TypeError: DOM object constructor cannot be called as a function when trying to use Promise.call.

Firefox throws when calling then in the subclassed promise: TypeError: 'then' called on an object that does not implement interface Promise.

Is this by design? __proto__ works but... you know.

@annevk
Copy link
Collaborator

annevk commented Jul 18, 2013

It'll eventually be possible, but currently engines haven't really progressed so far to make host objects subclassable.

@domenic
Copy link
Collaborator

domenic commented Jul 18, 2013

Is there anything the specs can say to make this more possible? Or do the specs already say that they should be subclassable, and implementations just haven't caught up?

@annevk
Copy link
Collaborator

annevk commented Jul 18, 2013

I think implementing @@create hasn't happened yet and will take a long time. Once that's done there might be some further work spec-wise, but that's far away.

@domenic
Copy link
Collaborator

domenic commented Jul 18, 2013

I don't think @@create is necessary for subclassability, except in very specific exotic object cases... After all, normal user-land promises are subclassable and don't have access to @@create.

@arv
Copy link
Collaborator

arv commented Jul 18, 2013

@domenic Promises have hidden internal state, do they not? If so, to do sub classing the instance must be created with the correct internal structure.

@juandopazo
Copy link
Author

Oh right! I didn't consider it is the same as any other host object. I guess we can use __proto__ in those engines that support promises, but it does complicate things a bit if we want to use polyfills.

@domenic
Copy link
Collaborator

domenic commented Jul 18, 2013

@arv right, they certainly do, but currently those engines create this internal state inside the non-stratified constructor (at least, that's what it seems like reading http://src.chromium.org/viewvc/blink/trunk/Source/bindings/v8/custom/V8PromiseCustom.cpp?pathrev=153560#1284). Later the allocation and initialization steps will be stratified, but I don't see why you can't derive from the current version and call Promise.apply(this, arguments) to set up the internal structure, plus initialize the promise, in one single un-stratified step.

@arv
Copy link
Collaborator

arv commented Jul 18, 2013

@domenic That would not be consistent with ES6. ES6 have [[Call]] throw if the internal data field is not present. See for example http://people.mozilla.org/~jorendorff/es6-draft.html#sec-15.14.1.1 , the 3rd step.

If map does not have a [[MapData]] internal data property, then throw a TypeError exception.

If we allowed Promise.apply(this, arguments) that would be future hostile.

@domenic
Copy link
Collaborator

domenic commented Jul 18, 2013

Ah, I see now. Thanks. :(

@difosfor
Copy link

difosfor commented Jul 8, 2014

Please correct me if I'm wrong but does this mean that in the foreseeable future native (e.g: browser) Promise implementations will not support subclassing?

I guess I will just have to feature detect and replace these limited implementations by a shim?

var useShim = typeof Promise === 'undefined' || !(function() {
    // Also ensure that Promise class can be properly extended
    var objectCreate = Object.create || function(proto) { function F() {} F.prototype = proto; return new F(); };
    function SubClass(fn) { Promise.call(this, fn); }
    SubClass.prototype = objectCreate(Promise.prototype);
    SubClass.prototype.constructor = SubClass;
    try { var sub = new SubClass(function() {}); sub.then(); return true; } catch (e) {}
}());

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants