Promise實現多圖預加載


Promise正如它的中文意思“承諾”一樣,保存着未來會發生事件(一般為異步操作)。Promise避免了“回調地獄”,寫法更加接近同步操作。說到同步,我更加喜歡async、await,它們書寫更貼近同步操作。

圖片加載往往是異步的,如果有操作需要等到所有的圖片加載完之后再執行,這時候就需要不斷的監聽所有圖片的加載情況。

ES5

利用ES5實現多圖預加載,可以通過計數器判斷有多少圖片加載完成。

復制代碼
var count = 0,    // 計數器
    imgs = [];

/*
* (Array)source 圖片url
* (Fun)cb 回調
*/ function preLoadImg(source, cb) { source.forEach(function(url, i) { imgs[i] = new Image(); imgs[i].onload = function() { if(++count === source.length) { cb && cb(); } } imgs.src = url; }) }
復制代碼

ES6

ES6原生提供了Promise對象,接下來用Promise改寫上面的代碼。

復制代碼
    // 預處理圖片
    function preLoadImg(source){
        let pr = [];
        source.forEach(url => {// 預加載圖片
            let p = loadImage(url)
                    .then(img => this.images.push(img))
                    .catch(err => console.log(err))
            pr.push(p);
        })

        // 圖片全部加載完
        Promise.all(pr)
                .then(() => {
                    // do sth
                });

    }
    // 預加載圖片
    function loadImage(url) {
        return new Promise((resolve, reject) => {
            let img = new Image();
            img.onload = () => resolve(img);
            img.onerror = reject;
            img.src = url;
        })
    }
復制代碼

Promise實際上是將回調操作獨立出來,當Promise狀態從pending(進行中)改為resolved(已完成),then注冊的函數就會被執行,如果狀態從pending改為rejected(已失敗),就會被catch捕獲。

這里想Promise.all傳入了一個Promise數組,數組中的Promise狀態均為resolved,Promise.all的狀態才會是resolved,否則Promise.all的狀態為rejected。也就是說,當所有圖片加載完成后,才會執行then中的函數。為了防止有圖片加載失敗,阻塞后續操作,為每一個p添加catch,捕獲reject,Primise.all就接受不到了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM