兼容性
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
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。






