web-dev-qa-db-fra.com

Comment accéder à la valeur d'une promesse?

Je regarde cet exemple de la documentation d'Angular pour $q mais je pense que cela s'applique probablement aux promesses en général. Ils ont cet exemple, copié textuellement avec leur commentaire inclus:

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

Je ne comprends pas comment cela fonctionne. Si je peux appeler .then() sur le résultat de la première .then(), en les chaînant, ce que je sais pouvoir, alors promiseB est un objet de promesse, de type Object. Ce n'est pas une Number. Alors, que veulent-ils dire par "sa valeur sera le résultat de la promesseA incrémentée de 1"? 

Suis-je censé accéder à cela en tant que promiseB.value ou quelque chose comme ça? Comment le rappel de succès peut-il retourner une promesse ET renvoyer "résultat + 1"? Il me manque quelque chose.

87

La fonction promiseA de then renvoie une nouvelle promesse (promiseB) qui est immédiatement résolue après la résolution de promiseA, sa valeur est la valeur de ce qui est renvoyé de la fonction de réussite dans promiseA.

Dans ce cas, promiseA est résolu avec une valeur - result et résout immédiatement promiseB avec la valeur result + 1.

L'accès à la valeur de promiseB s'effectue de la même manière que nous avons accédé au résultat de promiseA.

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

Quand une promesse est résolue/rejetée, il appelle son gestionnaire de succès/erreur:

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

La méthode then renvoie également une promesse: promiseB, qui sera résolue/rejetée en fonction de la valeur renvoyée par le gestionnaire de succès/d'erreur de promiseA .

Les gestionnaires de succès/erreur de promiseA peuvent renvoyer trois valeurs possibles qui affecteront le résultat de promiseB:

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

Fort de cette compréhension, vous pouvez comprendre ce qui suit:

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

L'appel retourne alors promiseB immédiatement . Une fois que promiseA est résolue, il transmettra le résultat au gestionnaire de succès de promiseA . Puisque la valeur renvoyée correspond au résultat de promiseA + 1, le gestionnaire de succès renvoie une valeur (option 2 ci-dessus) Ainsi, promiseB sera résolu immédiatement et le gestionnaire de succès de promiseB sera transmis au résultat de promiseA + 1.

15
pixelbits

.then fonction de promiseB reçoit ce qui est renvoyé de .then fonction de promiseA.

ici promiseA est un nombre qui sera disponible sous la forme du paramètre number dans la fonction de réussite de promiseB. qui sera ensuite incrémenté de 1

2
harishr

Analyser le commentaire un peu différemment de votre compréhension actuelle pourrait aider:

// promiseB will be resolved immediately after promiseA is resolved

Ceci indique que promiseB est une promesse mais sera résolu immédiatement après que promiseA soit résolu. Une autre façon de voir cela signifie que promiseA.then() renvoie une promesse affectée à promiseB.

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

Cela signifie que la valeur résolue par promiseA est celle que promiseB recevra comme valeur successCallback:

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

Vous pouvez facilement le faire en utilisant une méthode d'attente asynchrone en javascript.

Vous trouverez ci-dessous un exemple d'extraction d'une valeur de promesse WebRTC à l'aide d'un délai d'attente.

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

Dans le Node REPL, pour obtenir une connexion à la base de données correspondant à la valeur d'une promesse, j'ai adopté l'approche suivante:

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

La ligne avec await renverrait normalement une promesse. Ce code peut être collé dans le Node REPL ou s'il est enregistré dans index.js, il peut être exécuté dans Bash avec

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

ce qui vous laisse dans le Node REPL après avoir exécuté le script avec accès à la variable set. Pour confirmer que la fonction asynchrone est retournée, vous pouvez enregistrer connection par exemple, puis vous êtes prêt à utiliser la variable. Évidemment, on ne voudrait pas compter sur la résolution asynchrone de la fonction pour tout code du script en dehors de la fonction asynchrone.

0
dmstack

la réponse en pixels est correcte et vous devez toujours utiliser .then() pour accéder à la valeur d'une promesse dans le code de production.

Cependant, il existe un moyen d'accéder à la valeur de la promesse directement après sa résolution en utilisant la liaison node.js interne non prise en charge suivante:

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

AVERTISSEMENT: le processus.binding n'a jamais été conçu pour être utilisé en dehors du noyau de nodejs et l'équipe de base de nodejs cherche activement à le rendre obsolète

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

Cet exemple me semble explicite. Remarquez comment attendre le résultat et attendez que la promesse soit retournée.

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