循环后运行函数

时间:2018-08-02 11:17:48

标签: javascript node.js callback

我想在for循环完成循环之后运行一个函数,但是在我的情况下,for循环之后的函数甚至在循环结束之前运行。 这是我的代码

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

1 个答案:

答案 0 :(得分:2)

就像@RishikeshDhokare所说的那样,一切都是异步执行的。因此,诀窍是将任务拆分为单独的功能。

所以首先我们执行一个异步函数,您可以使用promise或async await

然后我们说在所有异步任务完成之后执行保存任务。

  

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))