Javascript 使用map或foreach异步/等待
我试图从我的数据库中检索一组产品价格,并假设我可以通过它们映射或foreach,+=价格到一个变量上,如下所示:Javascript 使用map或foreach异步/等待,javascript,node.js,reactjs,Javascript,Node.js,Reactjs,我试图从我的数据库中检索一组产品价格,并假设我可以通过它们映射或foreach,+=价格到一个变量上,如下所示: // Get Total exports.getTotal = (req,res) => { let productList = req.body; let total = 0; const results = productList.map(async (product) => { Product.findById(product._id)
// Get Total
exports.getTotal = (req,res) => {
let productList = req.body;
let total = 0;
const results = productList.map(async (product) => {
Product.findById(product._id)
.select('price')
.exec((err, foundProduct) => {
if (err){
console.log(`Error: Product with id ${product._id} not found.`);
} else {
console.log('Product price. ', foundProduct.price);
total += foundProduct;
}
})
});
Promise.all(results).then(data => console.log('Total is', total));
};
但是,总计的console.log始终返回0。我怀疑是console.log在映射和数据库查找承诺完成之前运行的问题
感谢您的指导。您以错误的方式使用exec exec,exec会给您一个承诺。你可以这样简化
// Get Total
exports.getTotal = (req, res) => {
const productList = req.body;
let total = 0;
const results = productList.map(async product => {
const foundProduct = await Product.findById(product._id).exec();
total += foundProduct;
return foundProduct;
});
Promise.all(results).then(data => console.log("Total is", total));
};
您以错误的方式使用exec exec返回承诺。你可以这样简化
// Get Total
exports.getTotal = (req, res) => {
const productList = req.body;
let total = 0;
const results = productList.map(async product => {
const foundProduct = await Product.findById(product._id).exec();
total += foundProduct;
return foundProduct;
});
Promise.all(results).then(data => console.log("Total is", total));
};
您忘记等待异步函数
等待Product.findById(Product.\u id)
此外,以功能性的方式编写也可以通过使用
//获取总数
exports.getTotal=(请求、回复)=>{
const results=req.body.reduce(异步(总计、产品)=>{
等待Product.findById(Product.\u id)
.选择('价格')
.exec((错误,foundProduct)=>{
如果(错误){
log(`Error:Product with id${Product.\u id}未找到。`);
返回总数
}否则{
console.log('Product price',foundProduct.price);
返回总数+=产品;
}
})
}, 0);
然后(data=>console.log('Total is',data));
};
您忘记等待异步函数等待Product.findById(Product.\u id)
此外,以功能性的方式编写也可以通过使用
//获取总数
exports.getTotal=(请求、回复)=>{
const results=req.body.reduce(异步(总计、产品)=>{
等待Product.findById(Product.\u id)
.选择('价格')
.exec((错误,foundProduct)=>{
如果(错误){
log(`Error:Product with id${Product.\u id}未找到。`);
返回总数
}否则{
console.log('Product price',foundProduct.price);
返回总数+=产品;
}
})
}, 0);
然后(data=>console.log('Total is',data));
};
数组的map()
,foreach()
和其他迭代方法不使用承诺。因此,使回调async
不会使内部迭代在对回调进行下一次迭代调用之前等待。此外,你的地图上会充满承诺,永远不会得到解决,因为你永远不会归还任何东西,这将相当于拥有
Promises.all([new Promise(), new Promise(), new Promise()])
您可以更改代码以创建新承诺的正确映射,然后在获取所有内容后计算总数。注意,由于exec()
本身会返回一个承诺,因此您只需返回:
const results = productList.map(product=> {
return Product.findById(product._id).select('price').exec();
});
Promise.all(results).then(values => {
let total = values.reduce((a, b) => a + b);
console.log(`Total: ${total}`)
});
您也可以在独立的async
函数中使用for循环,然后使用wait
async function getTotal(){
let total = 0;
for(let product of productList){
let price = await Product.findById(product._id).select('price').exec();
total+=price;
}
return total;
}
getTotal().then(total=>console.log(`Total: ${total}`));
数组的map()
、foreach()
和其他迭代方法不使用承诺。因此,使回调async
不会使内部迭代在对回调进行下一次迭代调用之前等待。此外,你的地图上会充满承诺,永远不会得到解决,因为你永远不会归还任何东西,这将相当于拥有
Promises.all([new Promise(), new Promise(), new Promise()])
您可以更改代码以创建新承诺的正确映射,然后在获取所有内容后计算总数。注意,由于exec()
本身会返回一个承诺,因此您只需返回:
const results = productList.map(product=> {
return Product.findById(product._id).select('price').exec();
});
Promise.all(results).then(values => {
let total = values.reduce((a, b) => a + b);
console.log(`Total: ${total}`)
});
您也可以在独立的async
函数中使用for循环,然后使用wait
async function getTotal(){
let total = 0;
for(let product of productList){
let price = await Product.findById(product._id).select('price').exec();
total+=price;
}
return total;
}
getTotal().then(total=>console.log(`Total: ${total}`));
数组的
map()
和foreach()
方法不使用承诺,因此使回调async
不会使内部迭代在对回调进行下一次迭代调用之前等待。数组的map()
和foreach()
方法不使用承诺,因此使回调异步
不会使内部迭代在对callback.cool进行下一次迭代调用之前等待。请随意将问题标记为已回答,以供其他人参考。酷。请随意将问题标记为已回答,以供其他人参考。