sql >> Databasteknik >  >> NoSQL >> MongoDB

Tryck inuti för varje med fråga som inte fungerar korrekt

Det är ett asynkront problem. Du fyller i värdet på arrayen i en återuppringning. Men på grund av händelseslingans natur är det omöjligt att någon av återuppringningarna kommer att ha anropats vid tidpunkten för console.log exekveras.

Du nämnde en lösning som involverar löften, och det är förmodligen den rätta vägen. Till exempel något i stil med följande:

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

Notera ändringen av forEach för att map ...på så sätt får du en mängd alla löften (jag antar att din findOne returnerar ett löfte på grund av .then ).

Sedan använder du en Promise.all att vänta på att alla löften ska lösa sig, och sedan bör du ha din array.

Sidanteckning:En mer elegant lösning skulle innebära att returnera newId inuti din .then . I så fall Promise.all kommer faktiskt att lösas med en uppsättning av resultaten av alla löften, vilket skulle vara värdena för newId .




  1. Reagera POST-förfrågningar med Express/Node och MongoDB

  2. MongoDB:hur jämför man $size of array med ett annat dokumentobjekt?

  3. Django-nonrel vs Django-mongodb vs Mongokit vs pymongo native

  4. redis för loggning