2017-10-02 1 views
1

J'essaie d'obtenir une liste d'entités correspondantes à partir d'une chaîne de requête. J'utilise s3 pour stocker mes objets.Problème avec la promesse async

Le problème est que la promesse qui résout la «promesse principale» est ansych ne retourne le tableau que lorsque setTimeOut. Sinon, il renvoie [undefined, undefined...].

mon code ressemble à ceci:

getEntities: (type, offset, limit, query) => { 
    return new Promise((resolve, reject) => { 

     seekKeys(type, offset, limit, query) 
      .then((response) => { 

       let entities = []; 


       if (response.hasBeenFiltered) { // This is not used yet. 
        for (let i = offset; i < response.keys.length && i < offset + limit; i++) { 
         entities.push(matchInstance(instance)) 
        } 

        resolve(entities) 

       } else { // here is where my issue's at. 
        console.log("Keys found: " + response.keys.length) 
        parseQuery(type, query) 
         .then((conditions) => { 

          let matches = response.keys.map((key) => { 
           readEntity(key).then((instance) => { 
            logger.debug(instance); // logs instances. 
            matchInstance(instance, conditions) 
             .then((isMatch) => { 
              logger.debug("isMatch", isMatch) // logs true/false ? 
              if (isMatch) { 
               entities.push(instance); 
              } 
             }) 
             .catch((err) => { 
              logger.error("Failed to match entity: ", err) 
             }) 
           }) 
            .catch((err) => { 
             logger.error("Failed to read entity: ", err) 
            }) 
          }); 
          /* 
          Promise.resolve(matches) 
           .then(() => { 
            setTimeout(() => { 
             logger.debug("Match count:", entities.length); 
             logger.debug("Matching entities:", entities) // logs result of entities 
            }, 5000) 
            //resolve(entities) 
           }) 
          */ 
          Promise.resolve(matches) 
           .then(() => { 
            logger.debug("Match count:", entities.length); 
            logger.debug("Matching entities:", entities) // logs [undefined, undefined ....] 
            resolve(entities) 
           }) 

         }) 
         .catch((err) => { 
          console.error("Failed to parse query: ", err) 
         }); 
      }) 
    }) 
}` 

Le format est un peu cassé. Je suis tout à fait sûr pourquoi. S'il vous plaît laissez-moi savoir si vous avez besoin de plus d'informations.

+0

Copie possible de [Comment renvoyer la réponse d'un appel asynchrone?] (Https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous- call) – Liam

+0

Évitez le ['anti-modèle de constructeur' 'Promise'] (https://stackoverflow.com/q/23803743/1048572?What-is-the-promise-construction-antipattern-and-how-to-avoid-it)! – Bergi

Répondre

2
let matches = response.keys.map((key) => { 
    // the mapping function: 
    readEntity(key).then((instance) => { 

La fonction de mappage ne semble pas renvoyer de valeur. Cela va créer un tableau mappé avec des éléments non définis.

let matches = response.keys.map((key) => { 
    return readEntity(key).then((instance) => { 
     // mapping function 

peut fonctionner mieux en remplissant matches avec des promesses à lire et entités de traitement. En attendant les promesses à remplir peut être accompli avec Promise.all, si

Promise.all(matches).then(... process the entities array 

est plus susceptible de travailler que

Promise.resolve(matches).then(... process entities 

qui n'attendre quoi que ce soit à moins asynchrone matches est une promesse en attente - mais Si tel était le cas, vous n'auriez pas besoin de le résoudre avant d'appeler le then.

Notez que l'indentation de code prête à confusion, vérifiez donc la console à la recherche d'erreurs pour voir si matches est dans la portée lors du traitement - Je n'ai pas pu voir que c'était le cas.

+0

Merci beaucoup! Ça fonctionne maintenant :) –