2016-03-30 7 views
4

Promise-Auflösung "hilfreich" macht verschiedene Dinge abhängig davon, ob der Rückgabewert von resolve() oder der Rückgabewert der Funktion, die an then() übergeben wird, ein Versprechen ist oder nicht.Wie entscheidet die Auflösung des Versprechens, ob ein Rückgabewert als Versprechen oder als einfacher Wert behandelt wird?

Daher erfordert das Verstehen und Vorhersagen des Verhaltens, genau zu wissen, welches Kriterium verwendet wird (oder verwendet werden darf), um zu bestimmen, ob etwas "ein Versprechen" ist, da ich den Ausdruck im obigen Satz verwende mag das niederschlagen. Ich interessiere mich für Promises/A + im Allgemeinen und ES6 native Versprechungen im Besonderen.

Mit Blick auf https://promisesaplus.com/, heißt es:

1.1 "promise" is an object or function with a "then" method 
    whose behavior conforms to this specification. 

Um zu sehen, was das bedeutet, ich sehe weiter in 2.2 „Die dann Methode“, und findet, dass sie auf einer Reihe von Verhalten Kriterien beruhen es deutlich zu machen unmöglich, algorithmisch zu entscheiden, ob ein gegebenes Objekt ein Versprechen ist oder nicht (Beweis durch Halteproblem). Und das ist in Ordnung; es bedeutet nur die Spezifikation des "hilfreich" Verhalten in Frage wird nicht den Begriff "ist ein Versprechen" direkt verwenden.

Also, auf der Suche nach der Spezifikation des "hilfreich" Verhalten, finde ich 2.3 "The Promise Resolution Procedure". Überraschung! Es tut den Begriff "ist ein Versprechen" direkt:

2.3.2 If x is a promise, adopt its state [3.4] 

Aber es rettet sich von einem Abstieg in die Bedeutungslosigkeit in der Fußnote:

[3.4] Generally, it will only be known that x is a true promise 
     if it comes from the current implementation. This clause allows 
     the use of implementation-specific means to adopt the state of 
     known-conformant promises. 

Mit anderen Worten, 2.3.2 didn‘ t wirklich bedeuten "Wenn x ist ein Versprechen", es bedeutete wirklich (und sollte gesagt haben, IMO) "Wenn x bekannt ist, um ein Versprechen zu sein".

Aber, wenn ich richtig verstehe, ist dieser Teil nur eine Abkürzung, die es nehmen darf, wenn es beweisen kann, dass es sicher ist, dies zu tun. Weitergehend scheint der relevante Abschnitt 2.3.3 zu sein, den ich wie folgt zusammenfasse: behandle den Rückgabewert x wie ein Versprechen Wenn x eine Eigenschaft namens "then" hat, die eine Funktion ist.

Also dann ruht alles auf der Definition von "x.dann ist eine Funktion". Was genau bedeutet das für jemanden, der eine konforme Bibliothek implementieren möchte, oder jemand, der vorhersagen möchte, was eine konforme Bibliothek tun/kann, wenn ich sie benutze? Ist es das gleiche wie typeof x.then === "function" zu sagen?

In der Hoffnung auf mehr Hinweise, ich schaute in die Spezifikation einer vermeintlich-konforme Implementierung (oder Reihe von Implementierungen), ES6 native Versprechungen, , die von der Promises Doc auf MDN verbunden ist. Ich glaube, der relevante Abschnitt ist 25.4.1.3.2. Es scheint, dass das fragliche Kriterium IsCallable (x.then) ist; Nach dem Link dazu, Ich sehe zu meiner Bestürzung, dass IsCallable keine eigentliche Funktion ist, sondern eine "abstrakte Operation", definiert in Bezug auf viele andere "abstrakte Operationen", die alles andere als einfach sind.

An dieser Stelle meine Hoffnung, jeden konformen Referenzcode zu sehen, die die fraglichen Entscheidung implementiert erscheint schnell :-(

Rückzug zu sichern zu meiner ursprünglichen Frage auf: „Wie Versprechen Auflösung nicht entscheiden, ob eine Behandlung Rückgabewert als Versprechen? ", I denke Ich habe es, wie ich oben erläutert, auf die spezifischere Frage herunterkochen: Genau was bedeutet die Promises/A + Spezifikation, wenn es heißt" ist eine Funktion "?

Wenn das eine einfache klare Antwort (die natürlich Raum für Variation zwischen den Implementierungen zulassen könnte), sofortige Follow-up-Fragen wäre:

  • Sind native Versprechen entsprechen der einfachen klaren Antwort?
  • Warum ist die Umsetzung von Verheißungen durch einheimische Versprechen/A + "ist eine Funktion" so kompliziert?
  • Was ist ein vernünftiger Weg für mich zu gewährleisten, dass mein Rückgabewert als ein Versprechen, wie ich es beabsichtige, oder als ein einfacher Wert, wie ich beabsichtige?
+0

'Was genau bedeutet die Promises/A + Spezifikation, wenn sie sagt "ist eine Funktion"? - Definitiv identisch mit der ECMA-Spezifikation - "Mitglied des Objekttyps, der als Subroutine aufgerufen werden kann" http://www.ecma-international.org/ecma-262/6.0/#sec-terms-and-definitions- Funktion – nekavally

Antwort

1

Also alles beruht auf der Definition von „x.then ist eine Funktion“. Was bedeutet das, ist es das gleiche wie typeof x.then === "function" zu sagen?

Ja, genau das. Abgesehen davon, dass der Zugriff auf x.then ausgelöst wird, müssen Sie all dies in einen try Block einbinden.

Warum ist die Umsetzung von Verheißungen durch einheimische Versprechungen/A + "ist eine Funktion" so kompliziert?

Weil es spec Terminologie ist. "function" ist grundsätzlich als "Callable Object" definiert, und isCallable ist nur der Algorithmus, um dafür zu testen. Es ist im Grunde derselbe Algorithmus, den die typeof operator verwendet, um zu bestimmen, ob die Zeichenfolge "function" zurückgegeben werden soll.


Btw, Sie werden interessiert sein an Regarding Promises/A+ Specification, what is the difference between the terms "thenable" and "promise"?.

+0

Sie sagen, IsCallable ist gleichbedeutend mit 'typeof x.then === "function"'? In den drei Abschnitten, auf die Sie verwiesen haben, sehe ich nichts. Können Sie in der ES-Spezifikation angeben, dass sie gleich sind und/oder beweisen, dass "typeof x.then ===" function "" die Bedingung ist, über die Promises/A + spec sprechen soll? Danke für den Link, ja das ist interessant. –

+0

@DonHatch: Ja, das ist es, was ich sage. Ich kann keinen weiteren Beweis dafür erbringen, dass "* implements *" dasselbe bedeutet wie "* has the method *", und ich kann keinen definitiven Hinweis nennen, der den Wortlaut von Promises/A + weiter erläutert, aber ich weiß es * dass das beabsichtigt ist. Sie können auch jede der in JS geschriebenen Versprechensimplementierungen überprüfen oder jedes Polyfill, das 'isCallable' benötigt - alle benutzen 'typeof'. – Bergi

+0

Wenn Sie sagen, dass Sie "wissen, dass dies das ist, was beabsichtigt ist", nehme ich an, dass Sie nur über die Promises/A + Spezifikation sprechen (und nicht die ES Frage) - in diesem Fall ok, das ist glaubwürdig, seit der Promises/A + Spezifikation ist in loser Sprache geschrieben.Ob die ES-Spezifikation isCallable äquivalent zu "typeof ... === 'function'" ist, es fällt mir wirklich schwer, eine so wichtige Äquivalenz zu glauben, ohne dass sie aus der Spezifikation hervorgeht oder eindeutig beweisbar ist. Ich denke, die Tatsache, dass Implementierungen typeof verwenden, ist ein Beweis, aber wenn die Spezifikation es nicht einmal impliziert, mein Gott, was für eine absurde Verschwendung von Worten wäre es. –

Verwandte Themen