【问题标题】:converting nested promise into async/await syntax将嵌套的 Promise 转换为 async/await 语法
【发布时间】:2021-02-28 13:20:41
【问题描述】:

我有一个嵌套的 promise,它获取数据然后将其呈现给 DOM。

我正在尝试将其转换为 async/await 语法,但因为它嵌套在 Promise 中。我无法转换它。

    fetch(searchUrl)
        .then(function (response) {
          return response.json()
        })
        .then(function (data) {
          searchLoader.style.display = "none";
          for (let i = 0; i < 10; i++) {
            let stock = `${data[i].name}, (${data[i].symbol})`;
            listOfStocks.innerHTML += `<li class="list-group-item"><a href="./company.html?symbol=${data[i].symbol}">${stock}<a/></li>`;
            // console.log(data[i].symbol)
          }
          return Promise.all(data.map(item => fetch(`${BaseUrl}company/profile/${item.symbol}`)));
        })
        .then(function (response) {
          return Promise.all(response.map(x => x.json()));
        })
        .then(function (data1) {
          console.log(data1);
          for (let i = 0; i < listOfStocks.children.length; i++) {
            if (data1[i].profile.changes >= 0) {
              listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc" style="color:green;"> ${data1[i].profile.changesPercentage}</span>`;
            } else {
              listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc"> ${data1[i].profile.changesPercentage}</span>`;
            }
          }

谢谢

【问题讨论】:

  • 忽略Promise.all(…) 表达式,并像对待任何其他承诺一样对待它。里面没有什么可以转换的。你能告诉我们你将线性then 链转换为async/await 的尝试吗?
  • 我正在添加作为答案-我重新尝试重构代码,它看起来还可以。

标签: javascript async-await fetch promise.all


【解决方案1】:

它似乎在工作@bergi - 感谢您的指点

  const response = await fetch(searchUrl);
      const data = await response.json();

      searchLoader.style.display = "none";
      for (let i = 0; i < 10; i++) {
        let stock = `${data[i].name}, (${data[i].symbol})`;
        listOfStocks.innerHTML += `<li class="list-group-item"><a href="./company.html?symbol=${data[i].symbol}">${stock}<a/></li>`;
        // console.log(data[i].symbol)
      }
      const response1 = await Promise.all(data.map(item => fetch(`${BaseUrl}company/profile/${item.symbol}`)));

      const data1 = await Promise.all(response1.map(x => x.json()));

      for (let i = 0; i < listOfStocks.children.length; i++) {
        if (data1[i].profile.changes >= 0) {
          listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc" style="color:green;"> ${data1[i].profile.changesPercentage}</span>`;
        } else {
          listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc"> ${data1[i].profile.changesPercentage}</span>`;
        }
      }
    ```

【讨论】:

  • 确实 :-) 不过不要忘记error handling on the fetch responses。我还建议不要先获取所有响应,然后再读取所有正文,而是在每个响应到达时正确执行。
【解决方案2】:

这就是将Promise.then(...).then(...).then(....) 链转换为async/await 代码的方法:-

async function processStuff(){
  const data = await fetch(searchUrl).then((response)=>response.json());

  searchLoader.style.display = "none";

       for (let i = 0; i < 10; i++) {
            let stock = `${data[i].name}, (${data[i].symbol})`;
            listOfStocks.innerHTML += `<li class="list-group-item"><a href="./company.html?symbol=${data[i].symbol}">${stock}<a/></li>`;
            // console.log(data[i].symbol)
          }
          const response = await Promise.all(data.map(item => fetch(`${BaseUrl}company/profile/${item.symbol}`)));

          const data1 = await Promise.all(response.map(x => x.json()));

               for (let i = 0; i < listOfStocks.children.length; i++)             {
            if (data1[i].profile.changes >= 0) {
              listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc" style="color:green;"> ${data1[i].profile.changesPercentage}</span>`;
            } else {
              listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc"> ${data1[i].profile.changesPercentage}</span>`;
            }  
          
            }

}
processStuff();

注意 - 我在这里为 Promise.all() 做的没什么特别的,因为它只是返回一个 Promise。如果只是Promise.resolve(2),方法是一样的。

【讨论】:

    【解决方案3】:

    应该是这样的:

    try {
      const response = await fetch(searchURL)
      const data = await response.json()
      searchLoader.style.display = "none";
      for (let i = 0; i < 10; i++) {
        let stock = `${data[i].name}, (${data[i].symbol})`;
        listOfStocks.innerHTML += `<li class="list-group-item"><a href="./company.html?symbol=${data[i].symbol}">${stock}<a/></li>`;
        // console.log(data[i].symbol)
      }
      const data1 = await Promise.all(data.map(async (item) => {
        const response = await fetch(`${BaseUrl}company/profile/${item.symbol}`)
        return response.json()
      }));
      for (let i = 0; i < listOfStocks.children.length; i++) {
        if (data1[i].profile.changes >= 0) {
          listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc" style="color:green;"> ${data1[i].profile.changesPercentage}</span>`;
        } else {
          listOfStocks.children[i].innerHTML = `<img class="logo-for-list" src="${data1[i].profile.image}" /> ${listOfStocks.children[i].innerHTML} <span class="color-prc"> ${data1[i].profile.changesPercentage}</span>`;
        }
      }
    } catch (e) {
      console.log(e)
    }

    【讨论】:

      猜你喜欢
      • 2020-02-22
      • 2019-08-11
      • 1970-01-01
      • 2019-11-08
      • 1970-01-01
      • 2023-04-08
      • 1970-01-01
      • 2019-12-14
      • 2012-10-25
      相关资源
      最近更新 更多