MongoDB
 sql >> Base de données >  >> NoSQL >> MongoDB

Poussez à l'intérieur de forEach avec la requête ne fonctionne pas correctement

C'est un problème asynchrone. Vous remplissez la valeur du tableau à l'intérieur d'un rappel. Mais en raison de la nature de la boucle d'événements, il est impossible que l'un des rappels ait été appelé au moment où le console.log est exécuté.

Vous avez parlé d'une solution impliquant des promesses, et c'est probablement la bonne approche. Par exemple, quelque chose comme ce qui suit :

exports = function(orgLoc_id, data) {
  // ...
  let stream_ids = [];
  const promises = data.map(function(stream) {
    return streamsCollection.findOne({ _id: stream.stream_id }, { type: 1, sizes: 1 })
      .then(res => { //if I comment this query it will push without any problem
        if (res) {
          let newId = new BSON.ObjectId();
          // ...
          stream_ids.push(newId);
        }
      })
  })

  Promise.all(promises).then(function() {
    console.log('stream ids: ' + stream_ids);

    //TODO
    // any code that needs access to stream_ids should be in here...
  });
};

Notez le changement de forEach pour map ... de cette façon, vous obtenez un tableau de toutes les promesses (je suppose que votre findOne renvoie une promesse à cause du .then ).

Ensuite, vous utilisez un Promise.all attendre que toutes les promesses se résolvent, puis vous devriez avoir votre tableau.

Remarque :une solution plus élégante consisterait à renvoyer newId dans votre .then . Dans ce cas Promise.all se résoudra en fait avec un tableau des résultats de toutes les promesses, qui seraient les valeurs de newId .