首页 > 解决方案 > 异步/等待总是返回一个承诺或未定义

问题描述

我一直在努力理解这有什么问题,但我仍然无法意识到我做错了什么。我正在尝试使用此 .map() 函数将用户购物篮中的每个项目作为 orderItem 添加到数据库中(数据库中的 orderItem 对应于产品,这与问题并不真正相关,但如果你是努力理解操作):

const orderItems= orderData.map(async product=>{
          const productId=product.id.slice(0,product.id.length-5)

          const targetProduct=await dataSources.ProductAPI.product(productId)

          const name=targetProduct.name
          const quantity=218327

          await dataSources.OrderItemAPI.createOrderItem(orderId,productId,name,quantity,{ttlInSeconds:60*20})
        })

然后,我尝试将上述数组orderItems中的每个 orderItem 映射到数据库中的实际产品,如下所示:

//我们找到每个orderItem对应的产品

 const productsCorrespondingToOrderItems= orderItems.map(async orderItem=>{
      const trial=await orderItem
      console.log(trial) <--- returns undefined
      // OR just logging orderItem returns a promise
      await dataSources.TransactionAPI.findProductFromOrderItem(orderItem.productId).then(x=>console.log(x))
    })

我已经检查了订单项目中的每个项目,它看起来还不错。问题是,当我简单地记录它时,每个orderItemin返回一个承诺,或者如果我等待它,则返回 undefined。productsCorrespondingToOrderItems我真的不明白,我做错了什么?太感谢了 !

标签: javascriptnode.jsasynchronousasync-await

解决方案


async函数总是返回一个承诺。你没有从你的map回调中返回任何东西,所以由于回调是async函数,它们返回用undefined.

如果您想等待您的map操作中的所有承诺都得到履行,请使用Promise.all结果。Promise.all返回一个承诺,该承诺将通过您给它的承诺的履行值数组来履行(如果它们全部履行)或在其中任何一个第一次拒绝时被拒绝。await您可以使用(在async函数中)或通过调用.then/来等待该承诺.catch

这是一个示例,假设您正在执行的代码map不在async函数中:

// If not in an `async` function
Promise.all(orderData.map(async product => {
    const productId = product.id.slice(0, product.id.length - 5);
    const targetProduct = await dataSources.ProductAPI.product(productId);
    const name = targetProduct.name;
    const quantity = 218327;

    const orderItem await dataSources.OrderItemAPI.createOrderItem(
        orderId,
        productId,
        name,
        quantity,
        { ttlInSeconds: 60 * 20 }
    );
    return await dataSources.TransactionAPI.findProductFromOrderItem(orderItem.productId);
}))
.then(productsCorrespondingToOrderItems => {
    // ...use `productsCorrespondingToOrderItems` here...
})
.catch(error => {
    // ...handle/report error...
});

请注意,这是并行工作的。如果您想串联执行,请使用async函数和for-of循环。


推荐阅读