我想在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'
});
});
答案 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))