Асинхронная функция внутри цикла - PullRequest
0 голосов
/ 02 ноября 2018

Я создаю приложение, и у меня возникла проблема внутри цикла for.

Внутри моей функции я получил два массива в качестве аргументов (payload.data.start и payload.data.end), и я пытаюсь вставить его в mongodb. Мой код выглядит так

async function emplaceAval (state, payload, blockInfo, context) {
  for(var i=0 ; i<payload.data.start.length ; i++) // start and end have the same length
  {
    const user =await User.findOne({ 'account': payload.data.account })
    user.availability.push({start: new Date(payload.data.start[i]+'Z') , end: new Date(payload.data.end[i]+'Z')});
    await user.save();
  }
}

Проблема в том, что я часто теряю данные. Потеряв данные, я имею в виду, что i изменяется до user.save.

Я думаю использовать forEach, но у меня есть два массива, которые нужно сохранить вместе, поэтому я не могу.

Второе решение, которое я подумал, это создать индексный массив. Например, если длина моих массивов равна 5, я создам indexTable = [0, 1, 2, 3, 4] и буду использовать asyncForEach для этого массива. Но я не думаю, что это решение является предпочтительным. Есть идеи? Заранее спасибо

1 Ответ

0 голосов
/ 03 ноября 2018

Из того, что я вижу здесь, циклы совершенно не нужны. MongoDB имеет оператор $push, который позволяет обновлять массив без предварительного извлечения документа. Также имеется опция $each, позволяющая «толкать» список элементов в одном обновлении.

Короче говоря, это всего лишь один запрос и ответ серверу на await:

// Transpose to array of objects for update
let availability = payload.data.start.map((e,i) =>
  ({ start: new Date(e+'Z'), end: new Date(payload.data.end[i] + 'Z') })
);

try { 
  // Perform the **one** update request
  let response = await User.updateOne(
    { 'account': payload.data.account },
    { '$push': { 'availability': { '$each': availability } } }
  );

  // maybe check the response
} catch(e) {
  // do something with any error
}

Это все, что тебе нужно сделать. Нет необходимости «зацикливаться» и гораздо меньше накладных расходов, чем возвращаться на сервер, извлекать документ и вносить изменения, а затем возвращать документ обратно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...