js之- 簡解Promise的resolved,rejected,Promise.all 和Promise.race(知識記錄)

1- Promise的三種狀態:

1- Pending(等待,未完成,進行中)
2- Resolved(成功)
3- Rejected(失敗)

2- Promise的三種狀態關係變化只有兩種:

1- Pending => Resolved(從 ‘等待’ 變成 ‘成功’ )
2- Pending => Rejected( 從 ‘等待’ 變成 ‘失敗’ )
3- 狀態一旦改變,無法再次改變

3- Promise可以用來解決:

1- 解決多次併發請求:通過Promise.all來獲取’所有 併發請求 都成功’ 後的數據集合
2- 解決回調地獄:通過.then,.catch,.all,.race解決 異步請求success回調裏繼續執行函數或者異步請求造成的層層嵌套,造成的可讀性差,難維護

4- Promise的resolved和rejected 以及 then和catch:先上代碼

function demo(){
        return new Promise((resolve,reject)=>{
            $.ajax({
                url: "http://api.local.com/?type=list", 
                method: "get",
                header: {'content-type': 'application/json'},
                success: res=>{
                	// 此處執行resolve(res),才能通過.then來調用,並且.then裏接收到的值就是這裏傳進去的
                    resolve(res) 
                },
                error: err=>{
                    reject(err)
                }
            });
        });
    };
    // 執行,查看結果
	demo().then(data=>{
        console.log( data , "成功")
    }, err=>{
        console.log( err , "失敗" )
    });
    
	// 第二種寫法,通過catch來捕獲reject錯誤失敗狀態
	demo().then(data=>{
        console.log( data , "成功")
    }).catch(err=>{
        console.log( err , "失敗catch" )
    });
  1. then返回一個新的Promise,裏面接收兩個參數,第一個參數(必選)爲resolve成功回調,第二個參數(可選)爲reject失敗回調
  2. catch是當promise拋出錯誤變時被調用,等同於then裏的第二個err參數
  3. success或者error的回調裏調用 resolve(res) 或者reject(err) 方法,並傳入返回參數。如果不執行對應函數,無法通過then來鏈式調用。執行但是不傳入參數,then裏則無法獲取返回參數。可自行敲代碼看下打印輸出

5- Promise,解決回調地獄,多層嵌套:

// 分成三個方法,每個方法單獨處理,只做自己的事情

// 1- 詢問帥不帥
    function handSome(){
        console.log('開始詢問帥不帥')
        return new Promise((resolve,reject)=>{
            $.ajax({
                url: "http://api.local.com/?type=list", 
                success: res=>{
                    console.log('很帥');
                    resolve(res);
                },
                error: err=>{
                    console.log('不帥');
                    reject(err)
                }
            });
        });
    };
    
// 2- 根據handSome回答,自己照鏡子確認
    function confirm(data){
        console.log('開始照鏡子:', data)
        return new Promise( (resolve,reject)=>{
            $.ajax({
                url: "http://api.local.com/?type=list",
                success: res=>{
                    console.log('照鏡子後確認很帥')
                    resolve(res)
                },
                error: err=>{
                    console.log('照鏡子後確認不帥')
                    reject(err)
                }
            });
        });
    }; 
    
// 3- confirm確認後,心情變化
    function determine(data){
        console.log('心情開始變化:',data)
        return new Promise( (resolve,reject)=>{
            $.ajax({
                url: "http://api.local.com/?type=list", 
                success: res=>{
                    console.log('很開心')
                    resolve(res)
                },
                error: err=>{
                    console.log('不開心')
                    reject(err)
                }
            });
        });
    };
  1. 先來第一種調用:只調用成功回調
handSome().then(confirm).then(determine)
// 開始詢問帥不帥
// 很帥
// 開始照鏡子: (2) [{…}, {…}]
// 照鏡子後確認很帥
// 心情開始變化: (2) [{…}, {…}]
// 很開心
handSome().then(confirm).then()
// 開始詢問帥不帥
// 很帥
// 開始照鏡子: (2) [{…}, {…}]
// 照鏡子後確認很帥
  1. 上面寫法比較簡潔,等同於下面寫法
handSome().then(res=>{
    confirm(res)
}).then(res=>{
    determine(res);
});
  1. 來個帶有報錯的完整寫法(假設所有接口都失敗)
handSome().then(confirm, err=>{
     console.log("handSome說我不帥")
}).then( determine, err=>{
     console.log("照鏡子後確實不帥")
}).then(res=>{},err=>{
     console.log("心情最後不開心")
});
// 開始詢問帥不帥
// 不帥
// handSome說我不帥
// 心情開始變化: undefined
// 不開心
// 心情最後不開心

根據上面調用的結果可總結出:

  1. 如果promise執行成功,並且還有then() 調用,則執行then() 中的第一個res參數
  2. 如果promise執行失敗,並且還有then() 調用,則執行then() 中的第二個err參數
  3. 有個特殊點,當err參數執行完畢後,後面還有then() 調用,則從then() 中的第一個參數開始,而不是繼續第二個參數調用
  4. 直到找不到then() ,開始狀態改變爲resolve或者rejected。

6- Promise的all和race

  1. Promise.all可以將多個Promise封裝成一個Promise。
  2. 並且,只有都請求成功的時候,纔會執行第一個參數,並且把多個請求結果封裝成數組返回
  3. 有執行失敗的,則返回最先被reject失敗狀態的值。
  4. 適合用在前端多個請求的情景
Promise.all([handSome(),confirm()]).then(res=>{
       console.log( "兩個接口都確認了,我很帥" )
       console.log( '兩個接口數據爲:',res)
},err=>{
       console.log( "兩個接口,有失敗的" )
       console.log( "失敗接口:",err)
});

都請求成功的打印輸出
在這裏插入圖片描述
有請求失敗的打印輸出
在這裏插入圖片描述

  1. Promise.race,哪個結果獲得的快,就返回那個結果,不管結果本身是成功狀態還是失敗狀態。
Promise.race([handSome(),confirm()]).then(res=>{
     console.log( '有先好的' )
     console.log( res )
})

打印結果
在這裏插入圖片描述
注:原先寫confirm方法,是用在handSome回調之後,可以獲取handSome返回的參數。在Promise.all和Promise.race中調用時,同步執行,所以confirm方法打印的data會undefined

如有錯誤,請大牛指出,及時修改

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章