ES6新增特性——Promise
一:為什麽會出現?
1、場景一:在很多業務需求中,你需要通過ajax進行多次請求,而且每次請求返回的數據需要作為參數進行下一次的請求,於是會出現ajax層層嵌套問題。多個請求操作層層依賴,加上每一層還會有復雜的業務邏輯需要處理,使得代碼可讀性很差,不直觀,難以維護和調試。
註:這種回調函數層層嵌套又稱為回調地獄
//請求A $.ajax({ success:function (res1) { //請求B $.ajax({ success:function (res2) {//請求C $.ajax({ success:function (res3) { ...... ....... } }) } }) } })
2、場景二:如果請求C依賴於請求A和B的結果,但A和B之間互不依賴,如果仍寫成A嵌套B,B嵌套C的形式,無疑是會消耗更多的等待時間。
故出現Promise對象來更合理和規範地處理異步操作。JS中所有代碼都是單線程執行,如果必須是異步執行,可以通過回調函數實現
二:如何使用?
Promise對象是全局對象,可以理解為一個類。
Promise對象有三種狀態:
pending:剛創建實例,表示初始化狀態
fulfilled:resolve方法調用的時候,表示操作成功
rejected:reject方法調用的時候,表示操作失敗
1、通過new生成一個實例,參數是一個匿名函數,其中有兩個參數resolve,reject
var pro = new Promise(function (resolve, reject) {
//pending狀態 if (‘操作成功‘) { resolve();//resolve:處理異步操作執行成功後的回調函數 fulfiied狀態 } else { reject();//reject:處理異步操作失敗後的回調函數 rejected狀態 } })
2、then()方法:用於處理操作後的處理程序
pro.then(function (res) { //執行resolve回調函數 }, function (error) { //執行reject回調函數 })
3、catch()方法:處理操作異常的程序
pro.catch(function (error) { //執行reject回調函數 })
綜合上面兩個方法,一般用then方法處理操作成功的程序,catch用來處理操作異常的程序
pro.then(function (res) { //執行resolve回調函數 }).catch(function (error) { //執行reject回調函數 })
完整示例:最後輸出結果為:執行成功
var pro = new Promise(function (resolve, reject) { //pending狀態 if (true) { resolve(‘執行成功‘);//resolve:處理異步操作執行成功後的回調函數 fulfiied狀態 } else { reject(‘執行失敗‘);//reject:處理異步操作失敗後的回調函數 rejected狀態 } }) pro.then(function (res) { //執行resolve回調函數 console.log(res) }).catch(function (error) { //執行reject回調函數 console.log(error) })
三:如何解決回調地獄問題?
var pro = new Promise(function (resolve, reject) { if (true) { resolve(‘執行成功‘); } else { reject(‘執行失敗‘); } }) pro.then(A) .then(B) .then(C) .catch(D) function A(res) { console.log(res) //執行成功 return ‘給下一個B請求傳參:成功執行A‘; } function B(res) { console.log(res) //給下一個B請求傳參:成功執行A return ‘給下一個C請求傳參:成功執行B‘; } function C(res) { console.log(res) //給下一個C請求傳參:成功執行B } function D(error) { console.log(error) }
可以通過多個then方法進行鏈式操作,通過return方式給下一個執行回調函數傳參,如上示例的結果是
執行成功
給下一個B請求傳參:成功執行A
給下一個C請求傳參:成功執行B
四:如何解決場景二問題?
Promise.all()方法:當參數中的實例對象的狀態都為fulfilled時,Promise.all()才會執行resolve函數
var pro1 = new Promise(function (resolve, reject) { setTimeout(resolve(‘成功執行1‘),5000); }); var pro2 = new Promise(function (resolve, reject) { setTimeout(resolve(‘成功執行2‘),1000); }); Promise.all([pro1,pro2]).then(function (res) { console.log(res) })
pro1在1000ms以後成功進入fulfilled狀態,但此時Promise.all還是不會有行動,需要等到pro2進入到fulfilled狀態時,才會進入then方法,故5000ms以後執行結果為:
[
‘成功執行1‘,
‘成功執行2‘
]
類似的方法還有Promise.race()方法,參數為Promise實例,只要有一個狀態發生改變,不管是成功fulfiied還是失敗rejected狀態,就會有返回,其他實例再有變化也不會再處理了。
var pro1 = new Promise(function (resolve, reject) { setTimeout(resolve,5000,‘成功執行1‘); }); var pro2 = new Promise(function (resolve, reject) { setTimeout(reject,1000,‘失敗執行2‘); }); Promise.race([pro1,pro2]).then(function (res) { console.log(res) }).catch(function (error) { console.log(error) })
執行結果為:
失敗執行2
ES6新增特性——Promise