2016-04-28 24 views
9

Ich habe eine Zusage, die Daten zurückgibt, und ich möchte das in Variablen speichern. Ist dies in JavaScript wegen der asynchronen Natur unmöglich und muss ich onResolve als Rückruf verwenden?So extrahieren Sie Daten aus einem Promise

Kann ich das irgendwie verwenden (z wickeln Sie es mit Asynchron/erwarten):

const { foo, bar } = Promise.then(result => result.data, errorHandler); 
// rest of script 

statt dessen?

Promise.then(result => { 
    const { foo, bar } = result.data; 
    // rest of script 
}, errorHandler); 

Hinweis: Drossel-Bibliothek statt native Implementierung verwendet, und ich kann nicht von Promise ändern/async warten oder Generatoren.

+0

Es ist möglich mit Javascript. Sie können Daten, die Sie bei einem Versprechen erhalten, einer Variablen zuordnen, die Sie zuvor deklariert haben. Und deine Variable wird den Wert haben, den du von der Verheißung erhalten hast. können Sie verweisen: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise –

+0

[ 'async/await'] (https://tc39.github.io/ ecmascript-asyncawait /) kommen! –

+0

@SandipNirmal Dies ist möglich, kann aber Fehler verursachen, da JavaScript nicht auf die Lösung warten kann. Außerdem müssen "const" in "let" geändert werden, was zu Nebenwirkungen führen kann. –

Antwort

9

NEIN Sie können nicht die Daten synchron aus einem Versprechen wie Sie in Ihrem Beispiel vorschlagen. Die Daten müssen innerhalb einer Callback-Funktion verwendet werden. Alternativ könnten die Versprechensdaten im funktionalen Programmierstil map()ed over sein.

Wenn Sie OK sind mit (Sie sollten es ist toll), dann können Sie Code schreiben, der synchron aussieht, aber die Asynchronität eines Versprechens behalten (siehe @loganfsmyth Kommentare).

Insgesamt, da Sie bereits ES6 verwenden, nehme ich an, dass Sie auch einen Transpiler verwenden. In diesem Fall sollten Sie unbedingt async/erwarten einen Versuch geben. Nur sicher sein, in der Entscheidung zu gewichten, dass wie heute noch keine ratifizierte Spezifikation ist.

+0

_" es ist großartig "_ Seit wann ist das großartig? – zeroflagL

+0

@zeroflagL async blockiert nicht mehr als Callback verspricht. Der Thread kann bei der Verarbeitung anderer Daten frei bleiben (d. H. Neue Anforderungen, wenn er sich in NodeJS befindet), während die Ausführung fortgesetzt wird, sobald das Versprechen verrechnet ist. Es ist nur eine andere Syntax. – silkAdmin

+0

Die Ausführung der Funktion wird gestoppt. Es ist nicht mit 'Promise.then'. Wenn Sie also ein Ergebnis in einem Event-Handler in einem Browser erwarten, ist das definitiv nicht großartig. – zeroflagL

1

Während Sie einen Wert von einem erwarteten Promise in einer asynchronen Funktion erhalten können (einfach weil die Funktion auf ein Ergebnis wartet), können Sie einen Wert nicht direkt aus einem Promise abrufen und in den gleichen Bereich zurückversetzen als das Versprechen selbst.

Das ist, weil „aus“ bedeuten würde versuchen, etwas zu nehmen, die in der Zukunft existiert (die schließlich gelöst Wert) und in einen Kontext (synchrone Variablenzuweisung) setzen, dass bereits in der Vergangenheit passiert ist.

Das heißt, Zeitreise. Und selbst wenn Zeitreisen möglich wären, wäre es wahrscheinlich keine gute Programmierpraxis, da Zeitreisen sehr verwirrend sein können :)

Im Allgemeinen, wenn Sie das Gefühl haben, dass Sie das tun müssen, ist es gut Zeichen, dass Sie etwas umgestalten müssen. Beachten Sie, dass, was Sie mit „Ergebnis => result.data“ hier machen:

Promise.then(result => result.data, errorHandler); 
// rest of script 

..ist bereits ein Fall mit dem Sie arbeitet (wörtlich: Mapping über) den Wert, indem es einen vorübergehenden Funktion. Aber unter der Annahme, dass "// Rest des Skripts" etwas Wichtiges in Bezug auf diesen Wert tut, möchten Sie wahrscheinlich fortsetzen Mapping über den jetzt aktualisierten Wert mit einer anderen Funktion, die dann etwas Nebeneffekt-y mit dem Wert (like Anzeige der Daten auf dem Bildschirm).

Promise 
    .then(result => result.data) 
    .then(data => doSomethingWithData)// rest of script 
    .catch(errorHandler); 

„doSomethingWithData“ wird aufgerufen, zu einem unbekannten Zeitpunkt in der Zukunft (wenn es jemals genannt).Aus diesem Grund ist es eine gute Übung, all dieses Verhalten in eine bestimmte Funktion zu kapseln und diese Funktion dann an die Promise-Kette anzuhängen.

Es ist ehrlich gesagt besser, weil es erfordert, dass Sie eine bestimmte Reihenfolge von Ereignissen, wird geschehen explizit explizit aus dem ersten Durchlauf durch die gesamte Ausführung Ihres Anwendungscode getrennt erklären.

Um es anders auszudrücken, dieses Szenario vorstellen, hypothetisch in der globalen, Umfang der obersten Ebene ausgeführt:

const { foo, bar } = Promise.then(result => result.data, errorHandler); 
console.log(foo); 
//...more program 

Was würden Sie es passieren erwarten? Es gibt zwei Möglichkeiten, und beide sind schlecht.

  1. Ihr gesamtes Programm (console.log und alles, was nach kommt es) würde haben zu stoppen und zu warten, bis das Versprechen auszuführen, bevor es wissen kann, was „foo“ würde ... ja könnte sein. (Dies ist was „erwarten“, innerhalb einer Asynchron-Funktion, in der Tat tun: es Pausen die gesamte Funktion, bis der Wert oder der Fehler kommt zurück)
  2. foo und bar würden nur nicht definiert werden (dies ist das, was tatsächlich passiert), da sie, synchron ausgeführt, nur nicht vorhandene Eigenschaften eines Promise-Objekts wären (das ist nicht der Wert , sondern ein Monad, das einen eventuellen Wert ODER einen Fehler einhüllt), was wahrscheinlich nicht einmal ist enthält noch einen Wert.
Verwandte Themen