Comment puis-je faire une promesse JavaScript retourner autre chose qu'une promesse?

38

J'ai une spécification d'un client pour l'implémentation d'une méthode dans un module:

 // getGenres():
 //  Returns a promise. When it resolves, it returns an array.

Si donné un éventail de genres,

['comedy', 'drama', 'action']

Voici une méthode squelette avec une promesse:

MovieLibrary.getGenres = function() {
  var promise = new Promise(function(resolve, reject) {
    /* missing implementation */
  });

  return promise;
};

Peut-on faire la promesse de retourner les données trouvées dans les genres? Existe-t-il un meilleur moyen de réaliser la description?

joint d'étanchéité
la source
8
Les promesses ne "renvoient" pas de valeur, elles les transmettent à un rappel (que vous fournissez avec .then ()). La spécification semble tout simplement confuse pour moi. C'est probablement essayer de dire que vous êtes censé faire resolve([genre1, genre2, ...]);dans la mise en œuvre de la promesse.
Ixrec

Réponses:

40

On dirait que vous ne comprenez pas comment les promesses sont utilisées. Vous retournez une promesse. Puis, plus tard, lorsque votre code résout la promesse, il le résout avec un résultat et ce résultat est transmis au .then()gestionnaire associé à la promesse:

MovieLibrary.getGenres = function() {
  var promise = new Promise(function(resolve, reject) {
    /* missing implementation */
    resolve(result);
  });

  return promise;
};

MovieLibrary.getGenres().then(function(result) {
    // you can access the result from the promise here
});
jfriend00
la source
5
Cela confirme que les promesses donnent les résultats escomptés.
sealocal
Probablement, vous ne comprenez pas pourquoi cela pourrait être nécessaire. En environnement, comme React Native avec Redux avec Realm, je dois attribuer l’état initial à Redux createStore. Il devrait être récupéré de Royaume, mais il retourne une promesse. Je veux juste bloquer jusqu'à ce qu'il renvoie des données car cela devrait être très simple et rapide. Au lieu de cela, je rencontre des problèmes pour combiner les promesses de domaines et les objets JSON habituels pour createStore ()
likern
26

Version mise à jour utilisant awaitplutôt que .then().

awaitarrête l'exécution jusqu'à ce que la promesse soit résolue (c'est-à-dire qu'elle a une valeur). Contrairement à l'utilisation, .then()vous pouvez simplement conserver awaitles valeurs lorsque vous exécutez diverses fonctions qui renvoient des promesses. L'exécution se poursuit sur la ligne suivante (c'est ce qu'on appelle le style direct). C'est aussi beaucoup plus agréable à regarder, car il est cohérent avec le reste de JavaScript, plutôt que .then()partout.

// Example function that returns a Promise that will resolve after 2 seconds
var getGenres = function() {
  return new Promise(function(resolve) {
    setTimeout(function(){
      resolve(['comedy', 'drama', 'action'])
    }, 2000);
  });
}

// We start an 'async' function to use the 'await' keyword
(async function(){
  var result = await getGenres()
  console.log('Woo done!', result)

  // But the best part is, we can just keep awaiting different stuff, without ugly .then()s
  var somethingElse = await getSomethingElse()
  var moreThings = await getMoreThings()
})()

Await est pris en charge par tous les navigateurs et nœuds actuels.

Mikemaccana
la source
1
Oh hey wow look, 3 questions SE sur ce sujet et enfin nous avons une réponse réelle!
Andrew