ES6中promise詳解及用法實例
一、什么是Promise
Promise是ES6異步編程的一種解決方案(目前最先進的解決方案是async和await的搭配(ES8),但是它們是基于promise的),從語法上講,Promise是一個對象或者說是構造函數,用來封裝異步操作并可以獲取其成功或失敗的結果。
二、為什么要使用promise
最重要也是最主要的一個場景就是ajax和axios請求。通俗來說,由于網速的不同,可能你得到返回值的時間也是不同的,但是我們下一步要執(zhí)行的代碼依賴于上一次請求返回值,這個時候我們就需要等待,結果出來了之后才知道怎么樣繼續(xù)下去。
三、promise的好處
1.可以避免多層異步調用嵌套問題(回調地獄)
2.Promise 對象提供了簡潔的API,使得控制異步操作更加容易(js執(zhí)行機制導致的異步問題)
這兩點在我ES6專欄的相關文章有很詳細的介紹,這里就不展開了
四、promise的三種狀態(tài)
Promise對象有三種狀態(tài),他們分別是:
1.pending: 等待中,或者進行中,表示還沒有得到結果
2.resolved(Fulfilled): 已經完成,表示得到了我們想要的結果,可以繼續(xù)往下執(zhí)行
3.rejected: 也表示得到結果,但是由于結果并非我們所愿,因此拒絕執(zhí)行
這三種狀態(tài)不受外界影響,而且狀態(tài)只能從pending改變?yōu)閞esolved或者rejected,并且不可逆
五、promise的用法
1.promise的實例方法
①then()得到異步任務的正確結果
②catch()獲取異常信息
③finally()成功與否都會執(zhí)行(尚且不是正式標準)
注意:then方法可以接受兩個函數,第一個函數為promise狀態(tài)為成功的回調函數,第二個函數為promise狀態(tài)為失敗的回調函數(可以不寫,一般用catch方法捕獲promise狀態(tài)為失敗的異常信息)
2.promise的對象方法(p1,p2,p3為promise的實例對象)
①Promise.all()并發(fā)處理多個異步任務,所有任務都執(zhí)行完成才能得到結果
Promise.all( [p1,p2,p3] ) .then ( (result) => {consoleog (result) })
②Promise.race()并發(fā)處理多個異步任務,只要有一個任務完成就能得到結果
Promise.race ( [p1,p2,p3] ).then ( (result)=>{ console. log (result) })
六、promise的特點
1.在Promise對象的構造函數中,將一個函數作為第一個參數。
2.而Promise對象的構造函數的第一個參數中的這個函數,就是用來處理Promise的狀態(tài)變化,這個函數的第一個參數表示promise的狀態(tài)為成功,第二個參數表示promise的狀態(tài)為失敗,這兩個參數(名字可以自己命名)都為一個函數,他們的作用分別是將promise狀態(tài)修改為resolved(成功)和rejected(失敗)。
<script> function fn(flag) { //構造函數 return new Promise(function(resolve, reject) { if (flag === true) { resolve('promise狀態(tài)為成功!') }; if (flag === false) { reject('promise狀態(tài)失??!') }; }) } console.log(fn(true)); </script>
控制臺運行:
3. Promise對象中的then方法,可以接收構造函數中處理的狀態(tài)變化,并分別對應執(zhí)行。then方法有2個函數參數,第一個函數接收resolved(promise狀態(tài)為成功)的執(zhí)行,第二個函數接收reject(promise狀態(tài)為失敗)的執(zhí)行。
<script> function fn(flag) { return new Promise(function(resolve, reject) { if (flag === true) { resolve('promise狀態(tài)為成功!') }; if (flag === false) { reject('promise狀態(tài)失敗!') }; }).then(function(res) { console.log(res); }, function(err) { console.log(err); }) } fn(true) fn(false) </script>
控制臺運行:
4.promise的狀態(tài)只能從 未完成->完成, 未完成->失敗 且狀態(tài)不可逆轉。
promise的異步結果,只能在完成狀態(tài)時才能返回,而且我們在開發(fā)中是根據結果來選擇來選擇狀態(tài)的,然后根據狀態(tài)來選擇是否執(zhí)行then()。
實例化的Promise內部會立即執(zhí)行,then方法中的異步回調函數會在腳本中所有同步任務完成時才會執(zhí)行。因此,promise的異步回調結果最后輸出。示例代碼如下:
var promise = new Promise(function(resolve, reject) { console.log('Promise instance'); resolve(); }); promise.then(function() { console.log('resolved result'); }); for(var i=0;i<100;i++) { console.log(i); /* Promise instance 1 2 3 ... 99 100 resolved result */
5.Promise.then()方法
①then()函數返回的實際也是一個Promise對象(無論函數內部返回什么類型的數據,函數都會進行加工返回一個promise對象)
<script> function fn(flag) { return new Promise(function(resolve, reject) { if (flag === true) { resolve('promise狀態(tài)為成功!') }; if (flag === false) { reject('promise狀態(tài)失??!') }; }) } console.log(fn(true).then()); </script>
控制臺運行:
②then()函數內部返回為普通值(非Promise類型的屬性),返回的普通值會直接傳遞給下一個then,通過then參數中函數的參數接收該值。
這時then()函數返回的Promise對象狀態(tài)為成功(resloved),then()函數的返回值為對象的成功值,如return 123,返回的Promise對象值為123,如果沒有返回值,是undefined
<script> const p = new Promise((resolve, reject) => { setTimeout(() => { resolve('用戶數據'); }) }); let result = p.then(value => { return 123; }, reason => { console.log(reason) }) console.log(result); result.then(function(res) { console.log(res); }) </script>
控制臺運行:
③ 當then()函數內部返回的是Promise類型的對象時,then()函數的返回的Promise對象的狀態(tài)值為這個Promise對象的狀態(tài)值,成功值也是如此,返回的該promise對象會調用下一個then方法。
<script> const p = new Promise((resolve, reject) => { setTimeout(() => { resolve('用戶數據'); }) }); let result = p.then(value => { return new Promise((resolve, reject) => { resolve('ok') }) }, reason => { console.log(reason) }) console.log(result); result.then(function(res) { console.log(res); }) </script>
控制臺運行:
④當then()函數內部果拋出異常,則then()函數的返回值狀態(tài)也是rejected
<script> const p = new Promise((resolve, reject) => { setTimeout(() => { resolve('用戶數據'); }) }); let result = p.then(value => { throw 123 }, reason => { console.log(reason) }) console.log(result); </script>
控制臺運行:
6.Promise.catch()方法
①catch()函數只有一個回調函數,意味著如果Promise對象狀態(tài)為失敗就會調用catch()方法并且調用回調
//catch()函數只有一個回調函數,意味著如果Promise對象狀態(tài)為失敗就會調用catch()方法并且調用回調函數 <script> const p = new Promise((resolve, reject) => { setTimeout(()=>{ reject('出錯啦') },1000) }) p.catch(reason => { console.log(reason) }) </script>
控制臺運行:
七、總結
1.promise其實就是一個對象或者說是構造函數
2.promise的出現(es6) 就是解決異步編程和回調地獄等問題,async和await的出現(ES8)就是基于promise的一種解決異步編程的終極解決方案(簡化代碼等等)
3.在前端中,ajax和axios都會用到異步編程,axios更是基于promise的,所以一定要掌握promise以及用async和await搭配promise的使用
到此這篇關于ES6中promise詳解及用法的文章就介紹到這了,更多相關ES6 promise用法內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
JavaScript高級程序設計 閱讀筆記(十九) js表格排序
js表格排序實現代碼,需要的朋友可以參考下2012-08-08