JavaScript事件关于图片预加载

本文探讨了如何避免JavaScript中图片加载的回调地狱问题,通过使用`load`事件、Promise和生成器函数来确保图片按设定顺序加载。作者分享了多种解决方案,包括 Promise.all() 和 async/await 的应用。
摘要由CSDN通过智能技术生成

普通的加载,不考虑加载图片的顺序

var arr = []
for (var i = 2; i < 7; i++) {
    var img = new Image();
    img.src = "./img/" + i + ".jpg";
    img.addEventListener("load", loadHandler);
}

function loadHandler(e) {
    arr.push(this);
    if (arr.length === 5) {
        // console.log(arr)
        arr.forEach(function(item) {
            console.log(item.src);
        })
    }
}

因为图片加载属于异步,小的图片会先加载出来,所有做了优化让图片按照设定的顺序加载出来

var arr = [];
var img1 = new Image();
img1.src = "./img/2.jpg";
img1.onload = function() {
    arr.push(img1);
    var img2 = new Image();
    img2.src = "./img/3.jpg";
    img2.onload = function() {
        arr.push(img2);
        var img3 = new Image();
        img3.src = "./img/4.jpg";
        img3.onload = function() {
            arr.push(img3);
            var img4 = new Image();
            img4.src = "./img/5.jpg";
            img4.onload = function() {
                arr.push(img4);
                var img5 = new Image();
                img5.src = "./img/6.jpg";
                img5.onload = function() {
                    arr.push(img5);
                }
            }
        }
    }
}

哇~ 哪位神人能写出这样的代码呀???

能这样写吗?肯定不能这样写,这样会造成回调地狱!!!

但是这样代码会很好理解,

没错,这样写出来只是为了理解怎么解决图片加载的顺序

var n = 2;
var arr = [];

function loadImage() {
    var img = new Image();
    img.addEventListener("load", loadHandler);
    img.src = "./img/" + n + ".jpg";
}

function loadHandler(e) {
    this.removeEventListener("load", loadHandler)
    arr.push(this);
    n++;
    if (n > 6) {
        loadFinishHandler();
        return;
    }
    loadImage();
}

function loadFinishHandler() {
    arr.forEach(function(item) {
        console.log(item.src)
    })
}

loadImage();

这样才是优化完成的代码,期待各路大神继续优化,


最后这个是用生成器函数写的预加载

//预加载
var arr=[]
function *loadImage(){
    for(var i=1;i<7;i++){
        var img=new Image();
        img.src=`./img/${i}.jpg`;
        yield img.onload=function(){
            arr.push(this);
            g.next();//强制同步
        }
    }
    arr.forEach(t=>{
        console.log(t.src);
    })
}


var g=loadImage();
g.next();


新更新!!!

用Promise做预加载,代码如下:

    function loadImage(src){
        return new Promise((resolve,reject)=>{
            var img=new Image();
            img.src=src;
            img.onload=function(){
                resolve(img);
            }
            img.onerror=function(){
                reject();
            }
        })
       
    }

    // var arr=[];
    // loadImage("./img/1.jpg").then(function(img){
    //     arr.push(img);
    //     return loadImage("./img/2.jpg")
    // }).then(function(img){
    //     arr.push(img);
    //     return loadImage("./img/3.jpg")
    // }).then(function(img){
    //     arr.push(img);
    //     return loadImage("./img/4.jpg")
    // }).then(function(img){
    //     arr.push(img);
    //     return loadImage("./img/5.jpg")
    // }).then(function(img){
    //     arr.push(img);
    //     return loadImage("./img/6.jpg")
    // }).then(function(img){
    //     arr.push(img);
    //     return loadImage("./img/7.jpg")
    // }).then(function(img){
    //     arr.push(img);
    //     return loadImage("./img/8.jpg")
    // }).then(function(img){
    //     arr.push(img);
    //     return loadImage("./img/9.jpg")
    // }).then(function(img){
    //     arr.push(img);
    //     return loadImage("./img/10.jpg")
    // }).then(function(img){
    //     arr.push(img);
    //     return loadImage("./img/11.jpg")
    // }).then(function(img){
    //     arr.push(img);
    //     return loadImage("./img/12.jpg")
    // }).then(function(img){
    //     arr.push(img);
    //     arr.forEach(t=>console.log(t.src))
    // })

    //优化()
    // Promise.all()
    // 将一个Promise组成的数组,放在Promise.all()中,
    // 这时候就会按照这个数组的顺序,异步一个个将所有promise内容调用执行
    // 最后将每个promise返回结果返回一个新数组中,通过执行then的函数带参传入
    for (let i = 0; i < 13; i++) {
        var p = loadImage(`./img/${i}.jpg`)
        arr.push(p)
    }
    Promise.all(arr).then(function(list){
        list.forEach(t=>console.log(t.src))
    })


//或者利用promise的async 和 await

function loadImage(src){
        return new Promise(function(resolve,reject){
            var img=new Image();
            img.src=src;
            img.onload=function(){
                resolve(img);
            }
            img.onerror=function(){
                reject();
            }
        })
       
    }
    
async function fn(){
    var arr=[];
    for(var i=1;i<13;i++){
        // await 会等待loadImage函数中resolve调用的时候,并且把resolve中传出参数返回给await前面的变量
        // 阻塞式异步
        var img=await loadImage(`./img/${i}.jpg`); 
        arr.push(img);
    }
    console.log(arr);
}

fn();

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端小码~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值