上篇的callback hell可以利用promise chaining寫成下面這樣,於是我們有的是以then方法一步接著一步做,取代巢狀callbacks的結構。
function delay(ms) {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
}
delay(1000)
.then(() => {
console.log("1 sec passed");
return delay(1000);
})
.then(() => {
console.log("2 sec passed");
return delay(1000);
})
.then(() => {
console.log("3 sec passed");
return delay(1000);
})
.then(() => {
console.log("4 sec passed");
return delay(1000);
})
.then(() => {
console.log("5 sec passed");
});
慢著,什麼是promise,什麼又是promise chaining?
promise是ES6發表用於處理非同步程序,可以把它看成一個空盒子,等著要裝非同步程序處理完的結果。一開始它裝的是pending,表示fetch的資料還沒來,圖片還在load,setTimeOut的時間還沒到等等的狀態;一旦非同步程序完成,則會回傳fullfilled或reject給promise,表示程序執行是成功還是失敗,狀態一旦轉到這個階段,則這個promise已經做完,狀態也無法再被改變。
如果使用fetch()來擷取資料會自動建立一個新的promise,不過像上面的例子,setTimeOUt()則需要使用Promise建構函式來新建一個新的promise物件。
而promise chaining則是使用方法來處理promise物件:then()來處理promise fullfilled之後的事,像是拿到資料後要怎麼過濾,然後呈現在網頁上,或者載入的圖片要渲染在哪個DOM的元素上,類似以上的動作,寫在then()的callback function裡;catch()則是用來處理報錯,在全部的promise chain程序中,若有任何一個地方出錯,都可以用catch()在console裡印出錯誤訊息,或渲染到網頁上,讓使用者知道現在發生什麼事;finally()則是處理無論promise成功或失敗都會發生的事,像是promise完成後的一些清理操作的情況,例如關閉資料庫連接、釋放資源、關閉文件等。
因為這些方法都是要處理promise物件,要做到這些方法個chaining,其實只要在每個方法的最後,return一個promise物件,就可以一直串下去,以取代callback hell裡一層又一層,像是全面啟動Inception那樣的多重夢境。
今天寫的不過只是使用
promise的基礎,但程式裡實際做的事其實是promisify
,接下來再繼續看看要使用Promise建構函式建立一個promise是怎麼一回事。
另外就是,感覺自己好像跳脫了一開始寫鐵人文的那種拘謹,也算是一種突破。
udemy-The Complete Javascript Course