繁体   English   中英

使用 Fetch 进行异步等待

[英]Async await with Fetch

我的 fetch 与 .then 完美配合,但我想通过使用asyncawait将其提升一个档次。 它应该等待所有 5 个 API 调用,然后放置答案,相反,它会在每个 API 调用上显示答案

 async function getPhotosFromAPI() { for (let i = 1; i <= 5; i++) { let albums = await fetch( `https://jsonplaceholder.typicode.com/photos/?albumId=${i}` ); let result = await albums.json(); let res = `<div class="album${i}"></div>`; document.querySelector(".display-images").innerHTML += res; for (let j = 1; j <= 5; j++) { document.querySelector( `.album${i}` ).innerHTML += `<img src="${result[j].url}"/>`; } } console.log(result); } async function showPhotos() { await getPhotosFromAPI(); document.getElementById("#loader").style.display = "none"; } showPhotos();

 document.getElementById("img").style.display = "block"; for (let i = 1; i <= 5; i++) { fetch(`https://jsonplaceholder.typicode.com/photos/?albumId=${i}`) .then((response) => response.json()) .then((json) => { document.getElementById("img").style.display = "none"; const display = document.querySelector(".display-images"); const albumNo = document.querySelector(".album-no"); // document.getElementById('img').style.display = "block"; // document.getElementById('img').style.display = "none";] display.innerHTML += `<div class="album-${i}>`; for (let z = 1; z <= 5; z++) { display.innerHTML += `<img id="img" alt="pic-from-album${json[i].albumId}" src="${json[z].url}"/>`; } display.innerHTML += `<div>`; }); }

您要求代码通过在循环中对fetch的返回值(然后再次对json的返回值)使用await来等待每次fetch完成。 所以它会这样做:等到该请求完成,然后再继续下一个循环迭代。

如果您不想这样做,则需要一个接一个地开始每个fetch ,然后等待它们全部完成。 我可能会将其中一个的工作分解为一个函数,然后调用它五次,构建它返回的承诺数组,然后await Promise.all(/*...*/)那些承诺,一些沿着这些思路:

document.getElementById("img").style.display = "block";
// Fetch one item
const fetchOne = async (i) => {
    const response = await fetch(`https://jsonplaceholder.typicode.com/photos/?albumId=${i}`);
    if (!response.ok) {
        throw new Error(`HTTP error ${response.status}`);
    }
    const data = await response.json();
    document.getElementById("img").style.display = "none";

    const display = document.querySelector(".display-images");
    const albumNo = document.querySelector(".album-no");
    //   document.getElementById('img').style.display = "block";
    // document.getElementById('img').style.display = "none";]
    display.innerHTML += `<div class="album-${i}>`;
    for (let z = 1; z <= 5; z++) {
        display.innerHTML += `<img id="img" alt="pic-from-album${data[i].albumId}" src="${data[z].url}"/>`;
    }
    display.innerHTML += `<div>`;
};
// ...
await Promise.all(Array.from({length: 5}, (_, i) => fetchOne(i + 1)));
// All done

(我将带有.then的版本作为上述的起点,因为您的问题中的两个版本是如此不同,而您说带有.then的版本起作用了...另请注意,我将变量json重命名为data ,因为它不包含 JSON [它不是字符串],它包含解析JSON 的结果。)

您应该使用像 Promise.all 这样的并发获取方式来避免往返

async function getPhotosFromAPI() {
  let albums = await Promise.all(
    Array(5).fill().map((elem, index) => 
      fetch(`https://jsonplaceholder.typicode.com/photos/?albumId=${index+1}`)
    )
  )
  let results = await Promise.all(
    albums.map(album => album.json())
  )
  return results
}
//Display

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM