兼容性
promise兼容性
一、Promise 的狀態
Promise有3種狀態:
- Pending:進行中
- Resolved(Fulfilled):已完成
- Rejected:已失敗
Promise狀態的改變只有兩種:
- Pending --> Resolved
- Pending --> Rejected
這意味著,一個Promise對象resolve之后,狀態就一直停留在Resolved那里了,反過來reject也一樣。
這種特點的結果是,Promise對象的狀態改變之后,你再給它添加回調函數,這個函數也會執行。
這跟事件監聽器很不一樣 —— 你一旦錯過某個事件,就沒辦法再捕獲他了,除非這個事件再次發生。
二、 .then() 和 .catch()
Promise構造器接受一個函數作為參數,這個函數有兩個參數:resolve,reject,分別代表這個Promise實例成功之后的回調函數和失敗之后的回調函數。
舉個例子:
var promise = new Promise(function (resolve, reject) { var a = 1 if (a == 1) { resolve(a) } else { reject(error) } }) promise.then(function (value) { console.log(value); }).catch(function (error) { console.log(error); }) // 輸出: // 1
不管是then方法還是catch方法返回的都是一個新的Promise實例,這意味著Promise可以鏈式調用then和catch,每一個方法的返回值作為下一個方法的參數:
var promise = new Promise(function (resolve, reject) { var a = 1 if (a === 1) { resolve(a) } else { reject(error) } }) promise.then(function (value) { console.log(value++) return value }).catch(function (error) { console.log(error) }).then(function (value) { console.log(value++) }) // 輸出: // 1 // 2
如果其中一個then失敗了,它后面第一個catch方法就會接受這個錯誤并執行,然后繼續執行后面的方法,比如:
三、 Promise.resolve() 和 Promise.reject()
兩者都是是new promise()的快捷方式。
Promise.resolve(value)是下面代碼的語法糖:
new Promise(function (resolve) { resolve(value) })
所以
Promise.resolve(42).then(function(value){ console.log(value); }); // 等同于 var promise = new Promise(function (resolve) { resolve(42) }) promise.then(function (value) { console.log(value) })
Promise.reject(value)是下面代碼的語法糖:
new Promise(function(resolve,reject){ reject(new Error("出錯了")); });
四、 Promise.all() 和 Promise.race()
1. Promise.all()
接收一個Promise對象的數組作為參數,當這個數組里的所有Promise對象全部變為resolve的時候,該方法才resolve。
如果其中一個Promise對象為reject的話,則該方法為reject。
比如:
2. Promise.race()
使用方法和Promise.all一樣,接收一個Promise對象數組為參數。
只要其中一個Promise對象變為Resolved或者Rejected狀態,該方法返回,進行后面的處理。
看例子:
五、 用Promise封裝AJAX代碼
原生的AJAX代碼真的是又臭又長了,可以用Promise把它們封裝起來,每次使用只需要調用一下封裝好的函數就可以了:
之后想要使用AJAX,只需要一個簡單的get()函數就可以搞定啦!
有一個地方需要注意的是,在get()函數里面調用了req.onload,之前為什么這里不使用req.onreadystatechange呢?
上面已經說過,Promise的狀態的改變是單向的,一次性的,一旦改變,狀態就會凝固了,而我們代碼中判斷狀態的片段是這樣的:
if (req.readyState == 4 && req.status == 200) { resolve(req.response) } else { reject(Error(req.statusText)) }
我們在if...else語句中改變了Promise的狀態,也就是req.onreadystatechange只會被調用一次。那么如果用req.onreadystatechange的話,會出現什么結果呢?
我們永遠只能得到error~因為req的state一旦改變,req.onreadystatechange就會被調用,所以我們永遠只能捕捉到req的state為2的時候!
不得不說Promise真的很有趣!
作者:Lxylona
鏈接:https://www.jianshu.com/p/82237a7ca6e5
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。