斷斷續續學習es6也有一段時間了,趁著開學空閒對知識點做一些小結。
為什麼使用promise
談到Promise,我們知道,這是社群較理想的非同步程式設計解決方案。想要掌握promise,我們首先要知道其提出原因。promise的提出很好的解決了多個相互依賴的程式碼之間的巢狀問題,比如說C程式碼需要B程式碼的結果,B程式碼需要A程式碼的結果,用傳統的方案,會出現層層巢狀的情況,不易維護。
promise物件是什麼
promise物件一共有三種狀態
- pending(進行中)
- fulfilled(已成功)
- rejected
promise物件有幾種相關方法
let promise = new Promise((resolve,reject) => {
//....
resolve('2');
//....
//reject('4');
})
最簡單建立物件的方法,就是為resolve和reject的狀態分別傳遞引數,也就是成功後的資訊或是失敗時的提示,當然,不一定要兩種狀態同時都有。
then方法,接受兩個引數,第一個為fulfilled狀態下要進行的步驟,第二個引數可選,指的是rejected狀態下執行的方法
當然,更推薦使用catch方法來定義錯誤狀態下的方法,也和try...catch結構類似
promise
.then((data) => { //cb
// success
})
.catch((err) => {
// error
});
這個物件有幾個特點,
1.比如狀態一旦更改,就不會再發生變化,也就是說pending狀態一旦轉換成fulfuilled或rejected就不再變化了。
let promise = new Promise((resolve,reject) => {
resolve('2');
reject('4');
})
比如上面的程式碼,promise在進入fulfulled狀態後就不再發生變化了,因此reject的操作是無效的。
2.比如promise物件建立中的程式碼是同步的,而then方法是非同步的。
let promise = new Promise((resolve, reject) => {
console.log('1');
resolve('2');
});
promise.then((resolve,reject) => {
console.log(resolve);
})
console.log(3);
// 1 3 2
promise物件建立以後立即執行,故輸出1,then方法為非同步執行,被放入等待的實踐佇列,在本次事件迴圈結束時執行,故先列印3,最後列印2。
3.不會主動丟擲錯誤
這一點比較特別,意味著我們必須定義catch方法或then的第二個引數來獲取錯誤,不然,錯誤無法被發現
4.chain 鏈式結構
then函式的可以接另一個then函式,而then函式返回一個promise物件,因此,這一個promise物件就決定了執行後面的哪些方法
與promise相關的問題
then方法與settimeout
這一個問題非常典型,其實只要明白一點:settimeout在下一輪“事件迴圈”的時候開始執行,Promise.then()在本輪“事件迴圈”結束時執行。
setTimeout(function () {
console.log('1');
}, 0);
Promise.resolve().then(function () {
console.log('2');
});
console.log('3');
輸出3 2 1
其實,這些方法,還是要多使用,多練習,才能得心應手