1

I would like to run a function after the for loop done looping, but in my case the function after the for loop runs before the loop even finished. Here's my code

let orderedItems = [];

for (let i = 0; i < orderCode.length; i++) {
  menuModel.findOne({
    _id: orderCode[i]
  }, (err, order) => {
    if (order) {
      orderedItems.push(order.name);
    }
  });
}

console.log(orderedItems); // all the tasks below run before the loop finished looping

let orderData = new orderModel();
orderData._id = helpers.createRandomString(5).toUpperCase();
orderData.username = username;
orderData.orderCode = orderCode;
orderData.orderedItems = orderedItems;
orderData.totalPrice = 5;

orderData.save((err) => {
  if (err) {
    console.log(err);
    callback(500, {
      'Error': '1'
    });
  }
  callback(200, {
    'Message': 'Successfully ordered'
  });
});   
2

1 Answer 1

2

as @RishikeshDhokare said everything is executed asynchronously. so the trick is to split the tasks into separate functions.

so first we execute an async function you can use promises or async await

then we say after all the async tasks have been completed do the save task.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

const orderCode = [1, 2, 3]
const menuModel = {
  findOne: item => new Promise(resolve => resolve({
    _id: item._id,
    name: 'name'
  }))
}

class orderModel {
  save(cb) {
    return cb(null)
  }
}
/*
  ignore all above here i'm mocking your funcs 
  and vars so that the code works
*/

let orderedItems = [];

function getAllOrderedItems() {
  const promises = orderCode.map(id => {
    return menuModel.findOne({
      _id: id
    });
  })
  console.log('...start the request')
  // fire  all async items then resolve them all at once
  return Promise.all(promises)
    .then((data) => {
      console.log('...finished all requests')
      return orderedItems.concat(data);
    })
    .catch(err => console.log(err))
}

function handleSave(data) {
  let orderData = new orderModel();
  console.log(data)
  console.log('...start save')
  orderData.save((err) => {
    console.log('...save finished')
  });
}
//do all the async tasks then do the save task
getAllOrderedItems()
  .then((data) => handleSave(data))

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.