簡體   English   中英

異步方法中的 Promise.all

[英]Promise.all in Async Method

有一個我無法用 Promises 鍛煉的問題。 下面的代碼在 server.js 中有效,但我已將包含網絡調用的代碼拆分為 class,現在這種方法會導致問題。

getItemDetails 的行為類似於同步方法,在達到 .then() 后執行返回到 server.js 中的下一行,我不明白為什么會這樣。

Class:

async getItemDetails(itemList) {

    let itemDetails = [];    
    Promise.all(itemList.map(id => this.axios.get(`/api/Item/${id.ItemID}/details`)))
        .then(responses => {
            responses.forEach(
                response => itemDetails.push(response.data)
            )
        })
        .then(() => {
            return itemDetails;
        })
        .catch(error => {
            console.error(error);
        });
}

服務器.js

(async () => {

    let itemList = await getItems() // Calls API to get a list of Items

    let detailList = await getItemDetails(itemList); // Retrieve details for hundreds of items


})();

您處於異步 function 中,因此不要將 .then .then().catch()與 Promise.all 一起使用: asyncawait是 Promises 周圍的語法糖,旨在消除 then/then/then/ 的問題catch/then/catch/etc/etc 鏈接。 相反,您編寫的代碼基本上是 vanilla JS,除了在 promises/async 調用之前的戰術await

async getItemDetails(itemList) {
  const items = await Promise.all(
    itemList.map(id =>
      this.axios.get(`/api/Item/${id.ItemID}/details`)
    )
  );

  return items.map(response => response.data);
}

或者,或者,如果您真的想在 Promises 中明確地執行所有操作,請刪除async關鍵字,因為您不需要它:

getItemDetails(itemList) {
 return new Promise((resolve, reject) => {
  Promise.all(
    itemList.map(id =>
      this.axios.get(`/api/Item/${id.ItemID}/details`)
    )
  )
  .then(responses => resolve(responses.map(r => r.data))
  .catch(err => reject(err));
}

請注意,就調用者所知,這些是相同的函數,產生相同的結果: async function 返回 Promise, await只是將 ZB321DE3BDC299EC807E9F795D7 解析為 value 的簡寫代碼

編輯:刪除了我的代碼示例,另一個答案有更好的實現。

JavaScript 在異步之前處理同步代碼,需要解決承諾。 async/await允許編寫更少的嵌套代碼,盡管值得牢記:promise 仍然需要解析/拒絕。

或者,使用async/await並使用更同步的樣式重新編寫它(當然使用 await 作為 Promise)。

否則,JavaScript 會查看方法,看到它有異步工作要做,完成同步代碼並完成執行.then() ,當然這是在方法完成之后。

暫無
暫無

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

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