等待所有元素完全融入Promise.all

时间:2018-09-27 09:30:33

标签: javascript es6-promise

我一直在尝试用一个非常简单的示例来了解Promises的工作原理:提取大量图像,依次将其加载到页面上,计算加载的图像数量。

const addImg = url => {
    fetch(url)
        .then(validateResponse)
        .then(readResponseAsBlob)
        .then(showImage)
        .catch(Error);
}

function showImage(responseAsBlob) {
    const container = document.getElementById('img-container');
    const imgElem = document.createElement('img');
    container.appendChild(imgElem);
    const imgUrl = URL.createObjectURL(responseAsBlob);
    imgElem.src = imgUrl;
    return imgUrl;
}

document.getElementById("add").onclick = () => {
    document.getElementById("status").innerHTML = "Fetching...";
    Promise.all(urls.map(url => addImg(url)))
        .then(setTimeout(() => {
            document.getElementById("status").innerHTML = document.getElementsByTagName("img").length + " images";
        }, 0));
}

addImg函数从url获取图像,将其作为blob处理,showImage渲染添加新的img。当我尝试从一组网址中添加图片时,我注意到我想解决的一些问题:

  1. 图像不一定按顺序显示
  2. img计数不正确

我的第一个想法:如果我解构addImg函数,以便将每个步骤作为一个单独的诺言执行(先提取所有->然后验证所有->然后...等等),它可能会按照我的预期方式工作,但我不确定这是否是正确的方法。

1 个答案:

答案 0 :(得分:-1)

如果您使用async / await重写了代码,那么对您来说可能更有意义。如果您将AJAX通话改写为

const addImg = url => fetch(url)
      .then(validateResponse)
        .then(readResponseAsBlob)
        .then(showImage)
        .catch(Error);

然后您可以执行以下操作:

async function loadImages(){
  for(image in imageList){
    await addImg(image.url);
  }
  console.log('Images loaded');
}

这样,您的代码将在下一个图像加载之前等待每个图像加载完成。请注意,这不是很有效,但是如果您希望它们按顺序专门加载,那么可以轻松实现这一目的。