web-dev-qa-db-de.com

Wie kann ich auf den Wert eines Versprechens zugreifen?

Ich betrachte dieses Beispiel aus Angulars Dokumenten für $q, aber ich denke, dass dies wahrscheinlich für Versprechen im Allgemeinen gilt. Sie haben dieses Beispiel wortgetreu mit ihrem Kommentar kopiert:

promiseB = promiseA.then(function(result) {
  return result + 1;
});

// promiseB will be resolved immediately after promiseA is resolved and its value
// will be the result of promiseA incremented by 1

Mir ist nicht klar, wie das funktioniert. Wenn ich .then() über das Ergebnis der ersten .then() aufrufen kann, indem ich sie kette, wovon ich weiß, dass ich kann, ist promiseB ein Versprechungsobjekt vom Typ Object. Es ist kein Number. Was meinen sie damit, dass "ihr Wert das Ergebnis von promiseA ist, das um 1 erhöht wird"? 

Soll ich als promiseB.value oder so etwas darauf zugreifen? Wie kann der Erfolgsrückruf ein Versprechen zurückgeben UND "Ergebnis + 1" zurückgeben? Ich vermisse etwas.

87

Die promiseA-Funktion von then gibt ein neues Versprechen (promiseB) zurück, das sofort aufgelöst wird, nachdem promiseA aufgelöst wurde. Sein Wert ist der Wert der von der Erfolgsfunktion innerhalb von promiseA zurückgegebenen.

In diesem Fall wird promiseA mit einem Wert - result aufgelöst und löst dann sofort promiseB mit dem Wert von result + 1 auf.

Der Zugriff auf den Wert von promiseB erfolgt auf dieselbe Weise wie auf das Ergebnis von promiseA.

promiseB.then(function(result) {
    // here you can use the result of promiseB
});
79
Nayish

Wenn ein Versprechen gelöst/abgelehnt wird, ruft es seinen Erfolgs-/Fehlerbehandler auf:

var promiseB = promiseA.then(function(result) {
   // do something with result
});

Die then-Methode gibt auch ein Versprechen zurück: promiseB, das aufgelöst/abgelehnt wird abhängig vom Rückgabewert des Erfolgs/Fehler-Handlers von promiseA.

Es gibt drei mögliche Werte, die die Erfolgs-/Fehlerbehandler von promiseA zurückgeben können, die das Ergebnis von promiseB beeinflussen:

1. Return nothing --> PromiseB is resolved immediately, 
   and undefined is passed to the success handler of promiseB
2. Return a value --> PromiseB is resolved immediately,
   and the value is passed to the success handler of promiseB
3. Return a promise --> When resolved, promiseB will be resolved. 
   When rejected, promiseB will be rejected. The value passed to
   the promiseB's then handler will be the result of the promise

Mit diesem Verständnis können Sie Folgendes verstehen:

promiseB = promiseA.then(function(result) {
  return result + 1;
});

Der Aufruf call gibt dann sofort promiseB zurück. Wenn PromiseA aufgelöst wird, wird das Ergebnis an den Erfolgs-Handler von promiseA übergeben. Da der Rückgabewert PromiseA ist, erhält der Erfolgs-Handler einen Wert (Option 2). promiseB wird sofort aufgelöst, und der Erfolgsbehandler von promiseB wird das Ergebnis von promiseA + 1 übergeben.

15
pixelbits

Die .then-Funktion von promiseB empfängt, was von der .then-Funktion von promiseA zurückgegeben wird.

hier ist promiseA eine Zahl, die in der Erfolgsfunktion von promiseB als number-Parameter verfügbar sein wird. die dann um 1 erhöht werden

2
harishr

Wenn Sie den Kommentar etwas anders analysieren, als Sie es derzeit verstanden haben, kann dies hilfreich sein:

// promiseB will be resolved immediately after promiseA is resolved

Dies besagt, dass promiseB ein Versprechen ist, das jedoch sofort nach Auflösung von promiseA aufgelöst wird. Eine andere Sichtweise bedeutet, dass promiseA.then() ein Versprechen zurückgibt, das promiseB zugewiesen ist.

// and its value will be the result of promiseA incremented by 1

Dies bedeutet, dass der Wert, zu dem promiseA aufgelöst wurde, der Wert ist, den promiseB als Wert für successCallback erhält:

promiseB.then(function (val) {
  // val is now promiseA's result + 1
});
1
Jason Cust

Sie können dies einfach mit einer asynchronen Wartemethode in Javascript tun.

Im Folgenden finden Sie ein Beispiel zum Abrufen eines WebRTC-Versprechungswerts mithilfe eines Timeouts.

function await_getipv4(timeout = 1000) {
    var t1 = new Date();
    while(!window.ipv4) {
        var stop = new Date() - t1 >= timeout;
        if(stop) {
            console.error('timeout exceeded for await_getipv4.');
            return false;
        }
    }
    return window.ipv4;
}

function async_getipv4() {
    var ipv4 = null;
    var findIP = new Promise(r=>{var w=window,a=new (w.RTCPeerConnection||w.mozRTCPeerConnection||w.webkitRTCPeerConnection)({iceServers:[]}),b=()=>{};a.createDataChannel("");a.createOffer(c=>a.setLocalDescription(c,b,b),b);a.onicecandidate=c=>{try{c.candidate.candidate.match(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/g).forEach(r)}catch(e){}}})
    findIP.then(ip => window.ipv4 = ip);
    return await_getipv4();
};

0
OxFEEDFACE

In der Node REPL habe ich den folgenden Ansatz gewählt, um eine DB-Verbindung zu erhalten, die den Wert eines Versprechens hat:

let connection
try {
  (async () => {
    connection = await returnsAPromiseResolvingToConnection()
  })()
} catch(err) {
  console.log(err)
}

Die Zeile mit await würde normalerweise ein Versprechen zurückgeben. Dieser Code kann in den Node REPL eingefügt oder, wenn er in index.js gespeichert ist, in Bash mit ausgeführt werden

node -i -e "$(< index.js)"

dadurch bleiben Sie im Node REPL, nachdem Sie das Skript mit Zugriff auf die festgelegte Variable ausgeführt haben. Um zu bestätigen, dass die asynchrone Funktion zurückgegeben wurde, können Sie beispielsweise connection protokollieren und dann die Variable verwenden. Man möchte natürlich noch nicht damit rechnen, dass die asynchrone Funktion für jeden Code im Skript außerhalb der asynchronen Funktion aufgelöst wird.

0
dmstack

die Antwort von pixelbits ist korrekt und Sie sollten immer .then() verwenden, um auf den Wert eines Versprechens im Produktionscode zuzugreifen.

Es gibt jedoch eine Möglichkeit, auf den Wert des Versprechens direkt zuzugreifen, nachdem es aufgelöst wurde, indem die folgende nicht unterstützte interne node.js-Bindung verwendet wird:

process.binding('util').getPromiseDetails(myPromise)[1]

WARNUNG: Process.binding sollte nie außerhalb des nodejs-Kerns verwendet werden, und das nodejs-Kernteam ist bestrebt, es abzulehnen

https://github.com/nodejs/node/pull/22004https://github.com/nodejs/node/issues/22064

0
Zeus Lalkaka
promiseA(pram).then(
     result => { 
     //make sure promiseA function allready success and response
     //do something here
}).catch(err => console.log(err)) => {
     // handle error with try catch
}
0
tomnyson

Dieses Beispiel finde ich selbsterklärend. Beachten Sie, wie Wait auf das Ergebnis wartet, und Sie versäumen es, dass das Versprechen zurückgegeben wird.

cryA = crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
Promise {<pending>}
cryB = await crypto.subtle.generateKey({name:'ECDH', namedCurve:'P-384'}, true, ["deriveKey", "deriveBits"])
{publicKey: CryptoKey, privateKey: CryptoKey}
0
Master James