2017-10-14 4 views
2

En général, en utilisant des classes ES6, il est assez facile aux classes composites commeComment correctement Promesses sous-classe avec Babel et ES6

class A extends B { /*...*/ } 

En matière de natif, les classes internes comme promesses si les articles lots suggèrent d'éviter le sous-classement. Babel lui-même ne parvient pas à transpirer significativement such use cases. Est-il en quelque sorte possible de transplanter correctement sous-classe ou même accorder l'exemple ci-dessous?

PS J'utilise Rollup avec ES2015 preset et aussi essayé de canaliser la transform-builtin-classes avec mon .babelrc

class P extends Promise { 
    foo(func) { 
    return this.then(func) 
    } 
    static bar(a) { 
    return a 
    } 
} 
+0

La plupart des navigateurs qui supportent les promesses supportent également les classes ES6, donc vous ne devriez probablement pas les transplanter. – Bergi

+1

Juste curieux, pourquoi voulez-vous sous-classe 'Promise'? Je n'ai jamais vu un bon cas d'utilisation pour cela. – Bergi

+0

Qu'essayez-vous d'accomplir? – guest271314

Répondre

1

Il y a des obstacles pour les classes intégrées héritage ES5 qui peut parfois être évité en utilisant une combinaison de Reflect.construct et Object.setPrototypeOf comme solution de contournement. C'est une méthode qui est utilisée par Babel transform-builtin-classes.

Le fait que cette méthode soit applicable dépend du fonctionnement de la classe intégrée. Dans le cas de Promise cela peut nécessiter une classe intermédiaire supplémentaire qui hérite de built-in, alors il peut être hérité en utilisant class ... extends.

function _P(executor) { 
    return Reflect.construct(Promise, [executor], P); 
} 

Object.setPrototypeOf(_P, Promise); 
_P.prototype = Object.create(Promise.prototype); 

class P extends _P { 
    static bar(arg) { 
    return new this(resolve => resolve(arg)); 
    } 

    foo(...fns) { 
    return this.then(...fns); 
    } 
} 

Ceci établit correct prototype chain. L'inconvénient de cette méthode est qu'elle est codée en dur à P sous-classe qui sera difficile à étendre davantage.

Une manière plus simple de procéder consiste à créer une instance de classe intégrée à la classe intermédiaire. Cela nécessite de reproduire l'API de classe d'origine en classe intermédiaire, mais comme il est petit, c'est un compromis acceptable pour la chaîne de prototype qui n'a pas de limites:

function _P(executor) { 
    this._promise = new Promise(executor); 
} 

Object.setPrototypeOf(_P, Promise); 
_P.prototype = Object.assign(
    Object.create(Promise.prototype), 
    { 
    then(...args) { 
     return this._promise.then(...args); 
    }, 
    ... 
    } 
); 

class P extends _P { ... } 

Il faut noter que cette fonctionnalité est déjà disponible via promise ponyfills déjà, y compris mapSeries. Leur utilisation en tant que fonctions auxiliaires autonomes est généralement une alternative préférable à la sous-classe P, étant donné que chaque promesse native devrait être convertie en P avec P.resolve afin de bénéficier de fonctionnalités supplémentaires.