简体   繁体   中英

Async function inside for loop

I am building an App and I have a problem inside a for loop.

Inside my function I got two arrays as arguments (payload.data.start and payload.data.end) and I am trying to push it inside the mongodb. My code looks like this

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

The problem is that lots of times I lose data. By losing data I mean that the i changes before user.save take place.

I consider to use forEach , but I have two arrays that need to be save together , so I cant .

The second solution I thought is to create an index array . For example if the length of my arrays is 5 , I will create an indexTable=[0 , 1 , 2 , 3 , 4 ] and I will use asyncForEach to this array. But i dont think that this solution is the preferable. Any ideas? Thanks in advance

From what I can see here the looping is completely unneccesary. MongoDB has a $push operator which allows update of an array without retrieving the document first. This also has an $each option to allow a list of elements to be "pushed" in the singe update.

In short this is just one request and response to the server to 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
}

That's all you need do. No need to "loop" and so much less overhead than going back and forth to the server retrieving a document and making changes then putting the document back.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM