Revenez d'une promesse alors ()


119

J'ai un code javascript comme celui-ci:

function justTesting() {
  promise.then(function(output) {
    return output + 1;
  });
}

var test = justTesting();

J'ai toujours une valeur indéfinie pour le test var. Je pense que c'est parce que les promesses ne sont pas encore résolues .. existe-t-il un moyen de renvoyer une valeur à partir d'une promesse?


21
la valeur de retour d'un then()appel est à nouveau une promesse, qui encapsule la valeur que vous avez renvoyée.
Sirko

Vous avez une erreur de syntaxe, je ne pense pas que cela analyse même.
djechlin

4
test n'est pas défini car justTesting ne renvoie rien dans votre exemple (vous n'avez pas de retour). Ajouter un retour et le test sera défini comme une promesse.
Jerome WAGNER

1
Merci pour le retour .. le point est d'attribuer la sortie +1 au test.
Priscy

4
Quelle est la variable promise. Vous ne l'affichez nulle part et vous ne renvoyez rien de votre justTesting()fonction. Si vous voulez une meilleure aide, vous devez décrire le problème que vous essayez de résoudre plutôt que de simplement nous montrer du code qui est tellement "désactivé" qu'il n'illustre même pas ce que vous essayez vraiment de faire. Expliquez le problème que vous essayez de résoudre.
jfriend00

Réponses:


136

Lorsque vous renvoyez quelque chose à partir d'un then()rappel, c'est un peu magique. Si vous renvoyez une valeur, la suivante then()est appelée avec cette valeur. Cependant, si vous retournez quelque chose de semblable à une promesse, le suivant then()attend, et n'est appelé que lorsque cette promesse se règle (réussit / échoue).

Source: https://developers.google.com/web/fundamentals/getting-started/primers/promises#queuing-asynchronous-actions


semble être à cause de cette raison, alors je peux faire une chaîne de promesse pour itérer un tableau avec des requêtes Ajax de manière synchrone dans stackoverflow.com/q/53651266/2028440
Bằng Rikimaru

84
N'a pas répondu à la question.
Andrew


1
Alors quelle est la solution?
Apurva

58

Pour utiliser une promesse, vous devez soit appeler une fonction qui crée une promesse, soit en créer une vous-même. Vous ne décrivez pas vraiment le problème que vous essayez vraiment de résoudre, mais voici comment créer vous-même une promesse:

function justTesting(input) {
    return new Promise(function(resolve, reject) {
        // some async operation here
        setTimeout(function() {
            // resolve the promise with some value
            resolve(input + 10);
        }, 500);
    });
}

justTesting(29).then(function(val) {
   // you access the value from the promise here
   log(val);
});

// display output in snippet
function log(x) {
    document.write(x);
}

Ou, si vous avez déjà une fonction qui renvoie une promesse, vous pouvez utiliser cette fonction et renvoyer sa promesse:

// function that returns a promise
function delay(t) {
  return new Promise(function(resolve) {
    setTimeout(function() {
      resolve();
    }, t);
  });
}

function justTesting(input) {
  return delay(100).then(function() {
    return input + 10;
  });
}

justTesting(29).then(function(val) {
  // you access the value from the promise here
  log(val);
});

// display output in snippet
function log(x) {
  document.write(x);
}


2
ce qui me jette, c'est le double return, c'est-à-dire justTestingdit return.then => return. Je sais que cela fonctionne bcs j'ai implémenté cela (bcs linting m'a obligé à, loin de new Promise), mais pouvez-vous expliquer comment comprendre / penser à cette paire retour / retour?
Ronnie Royston

2
@RonRoyston - Tout d'abord, la fonction à laquelle vous passez .then()est une fonction distincte de la fonction contenant, donc quand elle est appelée, elle a sa propre valeur de retour. Deuxièmement, la valeur de retour d'un .then()gestionnaire devient la valeur résolue de la promesse. Donc, .then(val => {return 2*val;})change la valeur résolue de valà 2*val.
jfriend00

13

Ce que j'ai fait ici, c'est que j'ai renvoyé une promesse de la fonction justTesting. Vous pouvez ensuite obtenir le résultat lorsque la fonction est résolue.

// new answer

function justTesting() {
  return new Promise((resolve, reject) => {
    if (true) {
      return resolve("testing");
    } else {
      return reject("promise failed");
   }
 });
}

justTesting()
  .then(res => {
     let test = res;
     // do something with the output :)
  })
  .catch(err => {
    console.log(err);
  });

J'espère que cela t'aides!

// old answer

function justTesting() {
  return promise.then(function(output) {
    return output + 1;
  });
}

justTesting().then((res) => {
     var test = res;
    // do something with the output :)
    }

Que se passerait-il si dans "// faire quelque chose avec la sortie" je mets une instruction return? Par exemple: j'aurais le "JustTesting (). Then ..." dans une fonction parent. Pourrais-je renvoyer une valeur dans la partie "alors"?
mrzepka

Si vous voulez retourner une valeur de // faire quelque chose avec la sortie, vous devrez ajouter un retour avant justTesing (). Exemple, "return justTesting (). Then ((res) => {return res;});
Vidur Singla

D'accord, c'est ce à quoi je m'attendais, je voulais juste m'en assurer :) Merci!
mrzepka

et si nous retournons le test à partir de là?
MeVimalkumar

3

Je préfère utiliser la commande "await" et les fonctions asynchrones pour me débarrasser des confusions de promesses,

Dans ce cas, j'écrirais d'abord une fonction asynchrone, celle-ci sera utilisée à la place de la fonction anonyme appelée sous "promise.then" partie de cette question:

async function SubFunction(output){

   // Call to database , returns a promise, like an Ajax call etc :

   const response = await axios.get( GetApiHost() + '/api/some_endpoint')

   // Return :
   return response;

}

puis j'appellerais cette fonction à partir de la fonction principale:

async function justTesting() {
   const lv_result = await SubFunction(output);

   return lv_result + 1;
}

Notant que j'ai renvoyé la fonction principale et la fonction secondaire aux fonctions asynchrones ici.


Bien ... L'utilisation de await l'a rendu beaucoup plus propre et a résolu le problème
karthikeyan
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.