在實際開發中,一定有情況是這樣的,一個頁面我們有多個地方請求了ajax,在這種情況下,我們要實現數據沒來之前出現我們炫酷的loading效果,而且要等到所有的ajax都請求完畢后,才讓我們的loading效果消失,那么問題來了,每個ajax請求數據的時間都是不確定的,我們這個loading效果結束的邏輯又應該放到哪里呢?就好比這樣(偽代碼模擬):
console.log('loading效果圖旋轉中') var timer1 = setTimeout(() => { console.log('第一個加載完成了'); }, '隨機的時間'); var timer2 = setTimeout(() => { console.log('第二個加載完成了'); }, '隨機的時間'); var timer3 = setTimeout(() => { console.log('第三個加載完成了'); }, '隨機的時間'); console.log('loading效果圖消失,我好慌,我應該放到哪里')
是不是很難受,你說每個請求的結束時間都不確定,我哪知道我應該放到哪里結束,別怕,給大家提供兩種解決方案,為了邏輯清晰,我就用一個延時器來給大家進行模擬了,莫要嫌棄:)
第一種解決方案:我們設置一個標識,比如loadingNums,當loadingNums等於0的時候,我們讓loading消失,接下來看代碼(應該用await和async來模擬的,但是重要的是思路,其他的不重要,你懂的):
var loadingNums = 3; console.log('loading效果圖旋轉中') var timer1 = setTimeout(() => { console.log('第一個加載完成了'); loadingNums--; if(loadingNums==0){ console.log('loading效果圖消失') } }, 1000); var timer2 = setTimeout(() => { console.log('第三個加載完成了'); loadingNums--; if(loadingNums==0){ console.log('loading效果圖消失') } }, 2000); var timer3 = setTimeout(() => { console.log('第二個加載完成了'); loadingNums--; if(loadingNums==0){ console.log('loading效果圖消失') } }, 3000);
頁面控制台打印效果:
第二種解決方案:我們可以用ES6的Promise,如果有不了解Promise的同學自行去查詢相關文檔,接下來開始我們的操作,Promise有一個all方法,接收一個參數,這個參數我們可以傳一個數組,在這個數組中我們可以寫多個Promise,看到這里你應該明白了,我們可以把所有的異步操作都用Promise包起來,然后都放到這個數組內(漂亮,給自己的聰明才智鼓個掌好不好),如你所想,這個all方法是可以等到數組中所有的Promise加載完成之后才去執行的,那還等什么,准備發車,看代碼:
console.log('loading效果圖旋轉中') var p1 = new Promise(function(resolve,reject){ setTimeout(() => { console.log('第一個加載完成了'); resolve(); }, 1000); }) var p2 = new Promise(function(resolve,reject){ setTimeout(() => { console.log('第三個加載完成了'); resolve(); }, 2000); }) var p3 = new Promise(function(resolve,reject){ setTimeout(() => { console.log('第二個加載完成了'); resolve(); }, 3000); }) Promise.all([p1,p2,p3]).then(function(){ console.log('loading效果圖消失'); })
頁面控制台打印效果:
好了已經很晚了,各位晚安早點睡覺,保護好自己的頭發~~~