1、什麼是Promise?
Promise是一個物件,儲存著非同步操作的結果(通常是非同步操作,也可以是同步操作),非同步操作結束後,會變更其狀態,然後呼叫註冊在then方法上的回撥函式。
從圖中可以看到Promise建構函式的原型上分別掛載了then
、catch
、finally
方法
2、先看簡單的用法
let promise = new Promise((resolve, reject) => {
let a = Math.random()
setTimeout(() => {
if (a > 0.5) {
resolve('success')
} else {
reject('error')
}
}, 1000)
})
promise.then(res => {
console.log(res)
}).catch(err => {
console.log(err)
})
複製程式碼
如果隨機數a大於0.5將會呼叫繫結在then方法上的回撥函式,並且列印出success
,反之則列印出error
3、Promise的狀態
Promise有三種狀態:
- pending: 初始狀態,既不是成功,也不是失敗狀態。
- fulfilled: 意味著操作成功完成。
- rejected: 意味著操作失敗。
pending狀態的promise可能會觸發fulfilled
狀態或者rejected
狀態,並傳入一個值給then方法,then方法包含了兩個引數(onfulfilled和onrejected),fulfilled
狀態會呼叫onfulfilled
方法,rejected
狀態onrejected
方法,即下面所示:
promise.then(function onfulfilled (res) {
console.log(res)
},function onrejected (err){
console.log(err)
})
複製程式碼
從第一張圖可以看到,then方法是定義在Promise的原型上的,原型上同時有catch方法,catch方法是
Promise.prototype.then(null, onrejected)
或者Promise.prototype.then(undefined, onrejected)
的別名
一般我們會才去catch方法來捕捉rejected狀態,這是因為onfulfilled如果有錯誤會被catch所捕捉到。
/ bad
promise.then(function(res) {
// success
}, function(err) {
// error
});
// good
promise.then(function(res) {
// success
}).catch(function(err) {
// error
});
複製程式碼
3、new Promise的快捷方式
Promise.resolve(error) 是和 Promise.reject(value) 類似的靜態方法,是 new Promise() 方 法的快捷方式。
Promise.resolve(42)
// 可以認為是下面的語法糖
new Promise(function(resolve){
resolve(42)
});
Promise.reject(new Error("出錯了"))
// 可以認為是下面的語法糖
new Promise(function(resolve,reject){
reject(new Error("出錯了"))
})
複製程式碼
4、Promise鏈式呼叫
從圖中可以看到then
方法可以鏈式呼叫,也就是在then
方法後面可以接著寫then
方法,這是因為then
方法返回的是一個新的Promise
例項,
那如何在then
方法之間傳值呢,就是第一個then
方法的值能夠傳遞給第二個then
方法,以此類推,答案非常簡單,就是在then
方法中return
相應值就可以了
function doubleValue(value) {
return value * 2
}
function increment(value) {
return value + 1
}
function output(value) {
console.log(value) // => (1 + 1) * 2
}
var promise = Promise.resolve(1);
promise
.then(increment)
.then(doubleValue)
.then(output)
.catch(function(error){
// promise chain中出現異常的時候會被呼叫
console.error(error)
});
複製程式碼
整體流程:
- Promise.resolve(1); 傳遞 1 給 increment 函式
- 函式 increment 對接收的引數進行 +1 操作並返回(通過 return )
- 這時引數變為2,並再次傳給 doubleValue 函式
- 最後在函式 output 中列印結果
5、Promise.all
Promise.all
接收一個 promise
物件的陣列作為引數,當這個陣列裡的所有promise
物件 全部變為fulfilled
或rejected
狀態的時候,它才會去呼叫 .then
方法。
6、Promise.race
與Promise.all
相對, Promise.race
是隻要有一個promise物件進入 fulfilled
或者 rejected
狀態的話,就會繼續進行後面的處理。
如上整理,有誤請指正。