2016-05-11 24 views
3

Ich hatte eine Worker Klasse erstreckt, die einen Rückruf akzeptiert, aber ich wollte den Rückruf entfernen, indem sie ein Promise machen, so kann ich nur new Worker(stuff, otherStuff).then(function() { ... });Fehler bei der JavaScript-Versprechen

Um dies zu tun, habe ich das extends Stichwort .

Zuerst bekam ich die ReferenceError: this is not defined Fehler bei der this.a = a; Zuordnung, aber ich fand heraus, dass das war, weil ich super();

Jetzt anrufen musste, gibt es TypeError: this.resolve is not a function an der this.resolve({output: 'ok'}); Linie, also habe ich versucht mit Gewalt hinzufügen this.resolve und this.reject Funktionen, aber der Fehler wird nicht weggehen.

Dies ist der (stark vereinfacht) Code:

class Worker extends Promise { 
    constructor(a, b) { 
     super((resolve, reject) => { 
      console.log('inside super'); 
      this.resolve = resolve; 
      this.reject = reject; 
     }); 

     console.log('start constructing'); 

     this.a = a; 
     this.b = b; 

     console.log('A: ' + JSON.stringify(a)); 
     console.log('B: ' + JSON.stringify(b)); 

     this.doStuff(); 

     if (!this.status) { 
      this.resolve({output: 'ok'}); 
     } else { 
      this.reject('There was an error'); 
     } 
    } 

    doStuff() {} 
} 

let a = {x: 1}; 
let b = {z: 2}; 

console.log('before creation'); 
let w = new Worker(a, b); 
console.log('after creation'); 
w.then(function() { 
    console.log('done'); 
}); 

ich verwende Knoten 6.1.0, die appearsPromise Subklassifizieren zu unterstützen ... was mache ich falsch?

+0

Eigentlich ist es 'this.resolve = resolve;' das sollte werfen - weil 'this' noch nicht initialisiert ist, bevor der' super' Aufruf – Bergi

+0

zurückgibt Kannst du uns deinen tatsächlichen Code zeigen? Ich verstehe nicht, warum Sie "Promise" hier unterordnen oder welcher Teil asynchron ist. – Bergi

+0

Der eigentliche Code verwendet eine Bibliothek (kue), die eine asynchrone Warteschlange implementiert und eine Reihe von "Tests" verarbeitet. Wenn die Verarbeitung beendet ist, ruft sie this.resolve auf, wenn es irgendwo einen Fehler gibt, ruft sie this.reject auf – wil93

Antwort

0

Die beste Vorgehensweise ist vermeiden, primitive Klassen zu erweitern, da sie Änderungen unterworfen sind. Wenn Sie sie erweitern, wird Ihre eigene Klasse für die Browser-/Engine-Gnade sorgen.

Wenn Sie versuchen, die Promise-Klasse zu erweitern, wird this nicht im Konstruktor definiert, da die meisten Engines heutzutage kein Sub-Classing-Versprechen unterstützen.

Darüber hinaus ist ein Arbeiter kein Versprechen. Ein Arbeiter soll arbeiten und ein Versprechen abgeben.

Eine Lösung besteht darin, das Wrapper- oder Factory-Muster anstelle der Vererbung zu verwenden.

Zum Beispiel können Sie einen Getter promise in Ihrer Klasse Worker definieren, der eine neue Promise Instanz erstellen und zurückgeben würde.

+0

Entferne die ersten beiden Absätze und du bekommst einen upvote :-) Die nativen Klassen sind erweiterbar und die Regeln dafür sind gut definiert. – Bergi

+0

@Bergi Ich poste nicht für upvotes. Darüber hinaus, wie native Klassen und alle nativen Codes, Objekte usw. nicht vom Benutzer selbst geschrieben werden, sind sie dem Anbieter ausgeliefert - wie diejenigen, die die Javascript/Typoskript-Engine geschrieben haben. Egal wie Menschen behaupten, dass solche Klasse erweiterbar sein soll bla bla bla, Menschen sind von Natur aus nicht vertrauenswürdig. Ich habe es auf eine harte Art gelernt, versuche also nicht, etwas anderes zu sagen. –

+0

Der gesamte JS-Code ist dem Engine-Implementor und Executor ausgeliefert. Die nativen Klassen sind in der ECMAScript-Sprachspezifikation gut definiert, und es gibt keinen Grund, diesem nicht zu vertrauen. Und Sie können keinen nützlichen JS-Code schreiben, ohne irgendwelche eingebauten Daten zu verwenden, also gibt es keinen Grund, der Erweiterbarkeit von Klassen weniger zu vertrauen als etwa der 'exec'-Methode von regulären Ausdruck-Objekten. – Bergi