Mon go DB возвращает неопределенные значения в массиве - PullRequest
2 голосов
/ 09 апреля 2020

У меня есть этот код, который принимает значение количества документов в данный день недели в MongoDB. И в качестве запроса на возврат массив «qweek» заполняется.

function dates(current) {
  var week = new Array();

  // Starting Monday not Sunday
  current.setDate((current.getDate() - current.getDay() + 1));

  for (var i = 0; i < 7; i++) {
    var dd = String(current.getDate()).padStart(2, '0');
    var mm = String(current.getMonth() + 1).padStart(2, '0'); //January is 0!
    var yyyy = current.getFullYear();
    var day = dd + '/' + mm + '/' + yyyy;

    week.push(day);

    current.setDate(current.getDate() + 1);
  }

  return week;
}

// Initialize the App Client
const client = stitch.Stitch.initializeDefaultAppClient("app-id");

// Get a MongoDB Service Client
const mongodb = client.getServiceClient(
  stitch.RemoteMongoClient.factory,
  "mongodb-atlas"
);

//projection config
const options = { // Match the shape of RemoteFindOptions.
  limit: 1000, // Return only first ten results.
  projection: { // Return only the `title`, `releaseDate`, and
    day: 1, //   (implicitly) the `_id` fields.
  },
  sort: { // Sort by releaseDate descending (latest first).
    releaseDate: -1,
  },
}

// Get a reference to the travels database
const db = mongodb.db("travels");

function displayCountTravels() {
  var daysweek = dates(new Date());
  var qweek = new Array();

  for (var l = 0; l < daysweek.length; l++) {
    db.collection("details")
      .find({
        "day": daysweek[l]
      }, options)
      .toArray()
      .then(docs => {
        qweek.push(docs.length);
      });
  }

  console.log(qweek);
  console.log(qweek[1]);

  return qweek;
}

В этом случае, когда я делаю запрос в консоли массива. Я получаю это возвращение:

console.log(qweek);
Log output:[]
0: 0
1: 0
2: 0
3: 2
4: 0
5: 0
6: 0
length: 7
__proto__: Array(0)

Возврат команды console.log(week);

Return of command

Но когда я пытаюсь получить значение по индексу. Элемент массива возвращается с неопределенным значением.

console.log(qweek[1]);

Выход журнала:

undefined

Возврат команды console.log(week[1]);

Return of command

Я хотел бы знать, почему значение приходит с undefined.

1 Ответ

0 голосов
/ 09 апреля 2020

По сути, это случай asynchronous поведения в Javascript. Кроме того, asynchronous вызовы выполняются в виде for..loop.

Краткое объяснение: Вызовы запроса mon go -db имеют характер async, и их выполнение выполняется не собираюсь ждать его окончания sh до достижения console.log(qweek), который находится за пределами блока then. В результате вы получите qweek как пустое [] или qweek[1] как неопределенное.

Пара способов решить эту проблему - Serializing with promises and async/await или использование Promise.all(). Предложил бы вам прочитать их, чтобы понять больше.

Использование async/await: синтаксис менее многословен и прост для понимания

async function displayCountTravels() {
  var daysweek = dates(new Date());
  var qweek = [];
  try {
    for (var l = 0; l < daysweek.length; l++) {
      /*wait for the promise to resolve before next iteration*/
      var docs = await db
        .collection("details")
        .find({ day: daysweek[l] }, options).toArray();

      qweek.push(docs.length);
    }
  } catch (e) {
    console.error(e);
  }

  console.log(qweek);
  console.log(qweek[1]);

  return qweek;
}

Использование Promise.all(...):

function displayCountTravels() {
  var daysweek = dates(new Date());
  var promises = [];

  /*each mongo query is a promise, collect and return*/

  for (var l = 0; l < daysweek.length; l++) {
    promises.push(
      db.collection("details").find({ day: daysweek[l] }, options).toArray()
    );
  }

  return Promise.all(promises);
}

/*Calling fn, getting results in then since Promise.all() itself is promise*/
displayCountTravels()
  .then((results) => {
    /*using map to get lengths of the documents returned and put it in qweek*/
    var qweek = results.map((e) => e.length);
    console.log(qweek);
    console.log(qweek[1]);
  })
  .catch((e) => {
    console.error(e);
  });
...