MongoDB
 sql >> Datenbank >  >> NoSQL >> MongoDB

Drücken Sie forEach nach innen, wenn die Abfrage nicht richtig funktioniert

Es ist ein asynchrones Problem. Sie füllen den Wert des Arrays in einem Callback aus. Aufgrund der Art der Ereignisschleife ist es jedoch unmöglich, dass bis zum Zeitpunkt der console.log einer der Rückrufe aufgerufen wurde wird ausgeführt.

Sie haben eine Lösung mit Versprechungen erwähnt, und das ist wahrscheinlich der richtige Weg. Zum Beispiel etwas wie das Folgende:

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...
  });
};

Beachten Sie die Änderung von forEach zu map ...auf diese Weise erhalten Sie ein Array aller Promises (ich nehme an, Ihr findOne gibt wegen .then ein Promise zurück ).

Dann verwenden Sie ein Promise.all zu warten, bis alle Versprechungen aufgelöst sind, und dann sollten Sie Ihr Array haben.

Randnotiz:Eine elegantere Lösung wäre die Rückgabe von newId innerhalb Ihres .then . In diesem Fall Promise.all wird tatsächlich mit einem Array der Ergebnisse aller Promises aufgelöst, was die Werte von newId wären .