Lage
Ich habe die folgende Funktion, die Promise verwendet .
var getDefinitions = function() {
return new Promise(function(resolve) {
resolve(ContactManager.request("definition:entities"));
});
}
var definitions = getDefinitions()
Der Inhalt von definitions
ist:
Promise {
[[PromiseStatus]]: "resolved",
[[PromiseValue]]: child
}
Der PromiseValue
direkte Zugriff auf die Eigenschaft gibt undefiniert zurück
var value = definitions.PromiseValue; // undefined
Frage
Was bedeuten die doppelten Klammern [[ ]]
bedeuten, und wie rufe ich den Wert [[PromiseValue]]
.
new Promise(function(){})
. Das[[PromiseStatus]]
von Chrome kann mit dem<state>
von Firefox verglichen werden . Ich verstehe nicht wirklich, worum es hier geht (vorausgesetzt, OP weiß, was ein Versprechen ist).ContactManager.request("definition:entities")
?Antworten:
Was ist das Zeug drin?
[[]]
Es ist eine interne Eigenschaft. Sie können nicht direkt darauf zugreifen. Native Versprechungen können nur
then
mit Versprechungen oder allgemein asynchron ausgepackt werden - siehe So geben Sie die Antwort von einem asynchronen Aufruf zurück . Zitieren der Spezifikation:Du kannst nicht
Im Ernst - was sind sie?
Sehr schön! Wie aus dem obigen Zitat hervorgeht, werden sie nur in der Spezifikation verwendet. Es gibt also keinen Grund, warum sie wirklich in Ihrer Konsole angezeigt werden.
Sagen Sie es niemandem, aber dies sind wirklich private Symbole . Der Grund dafür ist, dass andere interne Methoden darauf zugreifen können
[[PromiseValue]]
. Wenn io.js beispielsweise beschließt, Versprechen zurückzugeben, anstatt Rückrufe entgegenzunehmen, kann io.js schnell auf diese Eigenschaften zugreifen, wenn dies garantiert ist. Sie sind nicht nach außen ausgesetzt.Kann ich darauf zugreifen?
Nur wenn Sie Ihren eigenen Chrome- oder V8-Build erstellen. Möglicherweise in ES7 mit Zugriffsmodifikatoren. Ab sofort gibt es keine Möglichkeit, da sie nicht Teil der Spezifikation sind und über alle Browser hinweg funktionieren - sorry.
Wie bekomme ich meinen Wert?
getDefinitions().then(function(defs){ //access them here });
Was aber, wenn ein Fehler zurückgegeben wird? Fügen Sie in Bezug auf diese Fälle Folgendes am Ende (und außerhalb) Ihrer .then () hinzu.
.catch(function(defs){ //access them here });
Obwohl, wenn ich raten müsste - Sie konvertieren die API zunächst nicht richtig, da diese Konvertierung nur funktionieren würde, wenn die Methode synchron ist (in diesem Fall kein Versprechen zurückgeben) oder wenn sie bereits ein Versprechen zurückgibt, das gemacht wird es wurde behoben (was bedeutet, dass Sie die Konvertierung überhaupt nicht benötigen - nur
return
.quelle
Promise
, auf seinen umschlossenen Wert außerhalb von zuzugreifenthen
. Der Zweck von aPromise
besteht darin, vom fehlenden Rückgabewert einer nicht blockierenden Funktion zu abstrahieren, dh aPromise
repräsentiert einen "zukünftigen Wert". Sobald man diesen "zukünftigen Wert" (außerhalb vonthen
) offenlegen würde, würde diese Abstraktion sofort für die gesamte Berechnung verloren gehen..catch((values) => {})
nicht über in.then(() => {})
[[PromiseValue]]
in den devtools tatsächlich von den devtools generiert. Wenn Sie auf der Konsole die Eingabetaste drückenevaluateOnCallFrame
, wird die Nachricht an V8 gesendet, wodurch ein RemoteObject vom Subtyp zurückgegeben wirdpromise
. Es gibt explizite Ad-hoc-Unterstützung dafür, dass dies funktioniert. Die obige Antwort ist richtig (daher erhält der Inspektor diese Eigenschaften), aber nicht genau (so gelangen sie nicht dorthin - sie gelangen über explizite Debugger-Unterstützung dorthin)Ich bin heute auch auf dieses Problem gestoßen und habe zufällig eine Lösung gefunden.
Meine Lösung sieht folgendermaßen aus:
fetch('http://localhost:3000/hello') .then(dataWrappedByPromise => dataWrappedByPromise.json()) .then(data => { // you can access your data here console.log(data) })
Hier
dataWrappedByPromise
ist einePromise
Instanz. Um auf die Daten in derPromise
Instanz zuzugreifen , musste ich diese Instanz nur mit der Methode auspacken.json()
.Hoffentlich hilft das!
quelle
then(dataWrappedByPromise => dataWrappedByPromise.json())
===then(resp.json())
.then(data => { console.log(data)})
kann vereinfacht werden,.then(console.log)
aber Sie haben absolut Recht, dass die Funktion benötigt wird, um auf eine Konstante für diese Funktion zuzugreifen. Entschuldigen Sie die VerwirrungDieses Beispiel ist mit reagieren, aber zum größten Teil sollte es das gleiche sein.
Ersetzen Sie this.props.url durch Ihre URL, um sie abzurufen, damit sie für die meisten anderen Frameworks funktioniert.
Wenn Sie die Datei res.json () analysieren, wird der Versprechen- Wert zurückgegeben. Wenn Sie ihn jedoch an eine andere .then () -Methode weiter unten zurückgeben, können Sie ihn als Gesamtarray zurückgeben.
let results = fetch(this.props.url) .then((res) => { return res.json(); }) .then((data) => { return data; })
quelle
Wenn wir die Manpage lesen , können wir Folgendes sehen:
Hervorhebung von mir. Daher kann das, was Sie tun möchten, nicht ausgeführt werden. Die bessere Frage ist, warum Sie so auf den Versprechen-Status zugreifen müssen.
quelle
Versuchen Sie es mit await .
Anstatt
var value = definitions.PromiseValue
verwenden
var value = await definiton;
Dies könnte Ihren Zweck lösen, indem Sie den Versprechenswert liefern.
Beachten Sie, dass await nur in asynchronen Funktionen verwendet werden kann und eine ES2016-Funktion ist.
quelle
Ich denke, dass es gut damit gehen wird.
(async () => { let getDefinitions = await ( () => { return new Promise( (resolve, reject) => { resolve(ContactManager.request("definition:entities")); }); })(); )();
quelle
Für den Fall, dass die zurückgegebene Antwort HTML ist, kein JSON
fetch('http://localhost:3000/hello') .then(response => response.text()) .then(data => { // you can see your PromiseValue data here console.log(data) })
quelle