JavaScript 在等待之前加载所有图像

JavaScript all images loading before await

我有一个简单的 JavaScript 文件,它从本地设备获取多个图像文件并显示图像的缩略图。到目前为止一切顺利。

显示缩略图后,我有一个调用 addImages() 函数的按钮。我需要显示图像的幻灯片放映,一次一个,持续 3 秒。然而,正在发生的是所有图像同时显示,然后调用睡眠函数,然后删除图像。这是我的代码:

        function addImages() {
    var preview = document.querySelector('#display');
                
        async function readAndPreview(file) {
            var reader = new FileReader();
        
                reader.addEventListener("load", async function () {
                    var image = new Image();
                    image.height = 400;
                    image.width = 400;
                    image.title = file.name;
                    image.border = 5;
                    image.src = this.result;
                    preview.appendChild(image);
                    sleep(3000).then(()=> preview.removeChild(image))


                }, false);
        
            reader.readAsDataURL(file);
        }   

    if(files) {
            [].forEach.call(files, readAndPreview);
    }
    }

  function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

看起来代码迭代到 appendChild,然后再次开始,直到添加了所有图像,然后调用睡眠函数,然后调用 removeChild。为什么???

如有任何帮助,我们将不胜感激。谢谢

我已经按照你的建议修改了很多实现。

主要变化:-

  1. 有一个文件实例reader
  2. 只有一张图片,我们会在指定时间后继续更改 src url。 (在我看到您试图在一定时间后添加和删除相同的图像元素后得出这个结论)。所以是的,我假设焦点将始终是一次一张图像,所以下面的代码。
let files // you must have an array initialized I think
let reader;
const preview = document.querySelector('#display');
let image = new Image();
image.height = 400;
image.width = 400;
image.title = file.name;
image.border = 5;
preview.appendChild(image);

function initReader(){
        reader = new FileReader();
        reader.addEventListener("load", function () {
          image.src = this.result;   
         }, false);   
}

 function addImages() { 
        initReader();        
        async function readAndPreview() {
                for (let index = 0;index<files.length;index++){
                reader.readAsDataURL(files[index]);
                await sleep(3000);
         } 
        }   
        readAndPreview();      
    }

  function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }

我没有 运行 这个所以可能会有错误的范围。但是这种方法应该适用于您的用例。

这种方法也有改进的余地,可以从一幅图像平滑过渡到另一幅图像。通常可以通过 blob URL.createObjectURL 预加载所有图像,并将它们存储在一个数组中,我们在该数组上循环并更新图像 src ,就像我们上面所做的那样。会快很多,因为数据已经在客户端。