簡體   English   中英

Async/await 總是返回一個 promise 或 undefined

[英]Async/await always returns a promise or undefined

我一直在努力理解這有什么問題,但我仍然無法意識到我做錯了什么。 我正在嘗試將用戶購物籃中的每個項目作為訂單項添加到數據庫中,使用 .map() 函數(數據庫中的訂單項對應於產品,這與問題並不真正相關,但如果您是努力理解操作):

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

我已經檢查了訂單項目中的每個項目,看起來還不錯。 問題是productsCorrespondingToOrderItems中的每個orderItem返回八個承諾,當我只是記錄它時,或者如果我等待它則 undefined 。 我真的不明白,我做錯了什么? 非常感謝 !

async函數總是返回一個承諾。 您不會從map回調中返回任何內容,因此由於回調是async函數,因此它們返回使用undefined實現的承諾。

如果您想等待map操作中的所有 promise 完成, Promise.all在結果上使用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循環。

您沒有從地圖中返回任何內容,並且地圖不適用於 async/await。 這樣做是為了一次調用 api 一次(串行)。 如果您想同時(並行)等待多個 api 調用,請使用 TJ Crowder 的答案。

const orderItems= [];
for (const product of orderData) {
      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})
    })
    // push something to the orderItems array here!
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM