Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/40.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用map或foreach异步/等待_Javascript_Node.js_Reactjs - Fatal编程技术网

Javascript 使用map或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)

我试图从我的数据库中检索一组产品价格,并假设我可以通过它们映射或foreach,+=价格到一个变量上,如下所示:

// 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进行下一次迭代调用之前等待。请随意将问题标记为已回答,以供其他人参考。酷。请随意将问题标记为已回答,以供其他人参考。