簡體   English   中英

如何使用帶有 fetch 和 Promise.all 的循環?

[英]How to use loops with fetch and Promise.all?

所以我關注了一篇關於 Promise 的 MDN 文章,想知道如何修改以下代碼以適用於任意數量的文件(不僅僅是 3 個)。

function fetchAndDecode(url) {
  return fetch(url).then(response => {
    if(!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    } else {
      if(response.headers.get("content-type") === "image/jpeg") {
        return response.blob();
      } else if(response.headers.get("content-type") === "text/plain") {
        return response.text();
      }
    }
  })
  .catch(e => {
    console.log(`There has been a problem with your fetch operation for resource "${url}": ` + e.message);
  })
  .finally(() => {
    console.log(`fetch attempt for "${url}" finished.`);
  })
}

let coffee = fetchAndDecode('coffee.jpg');
let tea = fetchAndDecode('tea.jpg');
let description = fetchAndDecode('description.txt');

Promise.all([coffee, tea, description]).then(values => {
  console.log(values);
  // Store each value returned from the promises in separate variables; create object URLs from the blobs
  let objectURL1 = URL.createObjectURL(values[0]);
  let objectURL2 = URL.createObjectURL(values[1]);
  let descText = values[2];

  // Display the images in <img> elements
  let image1 = document.createElement('img');
  let image2 = document.createElement('img');
  image1.src = objectURL1;
  image2.src = objectURL2;
  document.body.appendChild(image1);
  document.body.appendChild(image2);

  // Display the text in a paragraph
  let para = document.createElement('p');
  para.textContent = descText;
  document.body.appendChild(para);
});

MDN 特別指出“如果您正在改進此代碼,您可能希望循環顯示要顯示的項目列表、獲取和解碼每個項目,然后在 Promise.all() 中遍歷結果,運行不同的 function 以顯示每個都取決於代碼的類型。這將使它適用於任意數量的項目,而不僅僅是三個。 我不知道如何做到這一點,並希望得到幫助。 謝謝。

代碼的第二部分可以概括如下:

let urls = ['coffee.jpg', 'tea.jpg', 'description.txt'];

Promise.all(urls.map(fetchAndDecode)).then(values => {
    let elem;
    for (let value of values) {
        if (value instanceof Blob) {
            elem = document.createElement('img');
            elem.src = URL.createObjectURL(value);
        } else if (typeof value === "string") {
            elem = document.createElement('p');
            elem.textContent = value;
        } else {
            console.log("unexpected value type");
            continue;
        }
        document.body.appendChild(elem);
    }
});
const resources = ['coffee.jpg', 'tea.jpg', 'description'];

const resourceRequests = resources.map(fetchAndDecode);

Promise.all(resourceRequests.then(values => {

...

是實施建議的一種方式。 這種方法可以更輕松地修改資源列表,但不會真正更改任何 Promise 代碼。

上面的.map代碼等價於 (resource => fetchAndDecode(resource)) 因為fetchAndDecode只接受.map將傳遞給它的第一個參數。

暫無
暫無

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

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