MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Empurre para dentro do forEach com a consulta não funcionando corretamente


É um problema assíncrono. Você está preenchendo o valor da matriz dentro de um retorno de chamada. Mas devido à natureza do loop de eventos, é impossível que qualquer um dos retornos de chamada tenha sido chamado no momento em que o console.log É executado.

Você mencionou uma solução envolvendo promessas, e essa é provavelmente a tática certa. Por exemplo algo como o seguinte:
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...
  });
};

Observe a mudança de forEach para map ...dessa forma você está obtendo uma matriz de todas as Promessas (estou assumindo que seu findOne está retornando uma promessa por causa do .then ).

Então você usa um Promise.all para esperar que todas as promessas sejam resolvidas, e então você deve ter seu array.

Nota lateral:uma solução mais elegante envolveria retornar newId dentro do seu .then . Nesse caso Promise.all irá realmente resolver com uma matriz dos resultados de todas as promessas, que seriam os valores de newId .