前言
昨天研究完原理 及 一點點低基礎 還有流程
趁著記憶猶新 來看看實際用法
Promise 實例
Promise的 then
、 catch
、 finally
方法,
都屬於Promise
的實例方法,都是存放在 Promise
的 prototype
上的
1 | console.log(Object.getOwnPropertyDescriptors(Promise.prototype)) |
以上是F12
看到的實例方法
then()
then
是實例狀態發生改變時的回調函數
,
- 第一個參數是
resolved狀態
的回調函數 - 第二個參數是
rejected狀態
的回調函數
then
方法返回的是一個新的
Promise實例,也就是promise
能鍊式書寫
的原因
1 | getJSON("/posts.json").then(function(json) { |
catch()
catch()方法是 .then(null, rejection)
或.then(undefined, rejection)
的別名,
用於指定發生錯誤時的回調函數
1 | getJSON('/posts.json').then(function(posts) { |
Promise
對象的錯誤具有“冒泡”性質,會一直向後傳遞,直到被捕獲
為止
1 | getJSON('/post/1.json').then(function(post) { |
一般來說,使用catch
方法代替then()
第二個參數
Promise
對象拋出的錯誤不會傳遞到外層代碼,即不會有任何反應
1 | const someAsyncThing = function() { |
瀏覽器運行到這一行,
會打印出錯誤提示ReferenceError: x is not defined,
但是不會退出進程
catch()
方法之中,還能再拋出錯誤
,通過後面catch
方法捕獲
到
再舉個例子:
1 | const promise = new Promise((resolve, reject) => { |
如果希望後續能夠執行 catch
,那麼需要拋出一個異常
1 | const promise = new Promise((resolve, reject) => { |
finally()
finally()
方法用於指定不管Promise
對象最後狀態如何,都會執行
的操作
1 | promise |
Promise API 也稱構造函數方法
總共有以下的方法:
Promise API | |
---|---|
all() | Promise.all() 方法用於將多個 Promise實例,包裝成一個新的 Promise實例 |
race() | Promise.race() 方法同樣是將多個Promise 實例,包裝成一個新的Promise 實例 |
allSettled() | Promise.allSettled() 方法接受一組Promise 實例作為參數,包裝成一個新的Promise 實例只有等到所有這些參數實例都返回結果,不管是 fulfilled 還是rejected ,包裝實例才會結束 |
resolve() | Promise.resolve() 將現有對象轉為 Promise對象 |
reject() | Promise.reject(reason) 方法也會返回一個新的Promise 實例,該實例的狀態為rejected |
all()
1 | const p = Promise.all([p1, p2, p3]); |
接受一個數組Array
(疊代對象)作為參數,數組成員都應為Promise實例
實例p的狀態由p1
、p2
、p3
決定,分為兩種:
- 只有
p1
、p2
、p3
的狀態都變成fulfilled
,p的狀態才會變成fulfilled
,此時p1
、p2
、p3
的返回值組成一個數組,傳遞給p的回調函數 - 只要
p1
、p2
、p3
之中有一個被rejected
,p的狀態就變成rejected
,此時第一個被reject
的實例的返回值,會傳遞給p的回調函數
注意,如果作為參數的
Promise
實例,自己定義了catch
方法,那麼它一旦被rejected
,並不會觸發 **Promise.all()
**的catch方法
1 | const p1 = new Promise((resolve, reject) => { |
如果p2沒有自己的catch
方法,就會調用 **Promise.all()
**的catch方法
1 | const p1 = new Promise((resolve, reject) => { |
race()
1 | const p = Promise.race([p1, p2, p3]); |
只要p1
、p2
、p3
之中有一個實例率先改變狀態
,p的狀態就跟著改變
率先改變的Promise
實例的返回值則傳遞給p的回調函數
1 | const p = Promise.race([ |
allSettled()
1 | const promises = [ |
resolve()
1 | Promise.resolve('foo') |
參數可以分成四種
情況,分別如下:
- 參數是一個
Promise
實例,promise.resolve
將不做任何修改、原封不動地返回這個實例 - 參數是一個
thenable
對象,promise.resolve
會將這個對象轉為 Promise對象,然後就立即執行thenable對象的then()
方法 - 參數不是
具有then()
方法的對象,或根本就不是對象,Promise.resolve
()會返回一個新的Promise 對象,狀態為resolved
- 沒有參數時,直接返回一個
resolved
狀態的Promise 對象
reject()
1 | const p = Promise.reject('出錯了'); |
Promise.reject()
方法的參數,會原封不動地變成後續方法
的參數
1 | Promise.reject('出錯了') |
使用場景
將圖片的加載寫成一個
Promise
,一旦加載完成,Promise的狀態就發生變化
1 | const preloadImage = function (path) { |
通過鍊式操作,將多個渲染數據分別給個then
,讓其各司其職。
或當下個異步請求
依賴上個請求結果的時候,我們也能夠通過鍊式操作
友好解決問題!!
1 | // 各自做各自的事 |
通過all()
實現多個請求合併在一起,匯總所有請求結果,只需設置一個loading
即可
1 | function initLoad(){ |
通過race()
可以設置圖片請求超時
1 | //請求圖片資源 |
看了那麼多網頁,終於有一點點點點理解了