Promise使用場(chǎng)景
- 回調(diào)地獄:當(dāng)你發(fā)送一個(gè)ajax請(qǐng)求谴麦,繼而又需要請(qǐng)求一個(gè)ajax請(qǐng)求蠢沿,并且此ajax請(qǐng)求參數(shù)是上一個(gè)ajax請(qǐng)求返回的參數(shù),然后匾效,又有一個(gè)ajax請(qǐng)求舷蟀。。面哼。這樣的調(diào)用野宜,就陷入了回調(diào)地獄。這個(gè)時(shí)候Promise是幫上忙的時(shí)候了嘿魔策!
- 代碼的可讀性和可維護(hù)性:將數(shù)據(jù)請(qǐng)求和數(shù)據(jù)處理明確區(qū)分開(kāi)(當(dāng)數(shù)據(jù)變得復(fù)雜匈子,就需要將數(shù)據(jù)請(qǐng)求和數(shù)據(jù)處理分離開(kāi),增加代碼的可讀性和可維護(hù)性)
Promise基本知識(shí)
- Promise的三種狀態(tài):
- pending:等待(進(jìn)行)狀態(tài)
- resolved:結(jié)束狀態(tài)闯袒,并且是成功執(zhí)行
- rejected:結(jié)束狀態(tài)虎敦,并且是失敗執(zhí)行
(注:三種狀態(tài)的轉(zhuǎn)變只有兩種情況,pending=>resolved政敢,pending=>rejected)
- Promise基本使用方法
Promise中then傳遞兩個(gè)參數(shù)其徙,和使用catch有什么區(qū)別
function fetch() {
return new Promise((resolve, reject)=> {
// resolve,預(yù)想的執(zhí)行情況喷户,其中resolve可以攜帶參數(shù)擂橘,也可以不帶參數(shù)
....
resolve(data)
// reject,非預(yù)想的執(zhí)行情況摩骨,其中reject可以攜帶參數(shù)通贞,也可以不帶參數(shù)
...
reject(err)
})
}
// 第一種 調(diào)用fetch,fetch().then()傳入兩個(gè)參數(shù)恼五,第一個(gè)是resolve()昌罩,第二個(gè)是reject()
fetch().then(function(data){
console.log('預(yù)想狀態(tài)執(zhí)行成功')
},
function(err) {
console.log('非預(yù)想狀態(tài)執(zhí)行')
})
// 第二種 調(diào)用fetch,使用catch來(lái)執(zhí)行reject
fetch().then(function(data){
console.log('預(yù)想狀態(tài)執(zhí)行成功')
}).catch(function(err) {
console.log('非預(yù)想狀態(tài)執(zhí)行')
})
}
(注:兩種方式調(diào)用fetch的不同之處:then傳入兩個(gè)參數(shù)function灾馒,代表的是異步操作拒絕茎用;而使用catch,代表中斷調(diào)用鏈睬罗,如果連續(xù)幾個(gè)異步任務(wù)轨功,其中某個(gè)一步任務(wù)處理失敗了,那么接下來(lái)的幾個(gè)任務(wù)很大程度上就不需要繼續(xù)處理了容达,那這個(gè)時(shí)候使用catch就是中斷了調(diào)用鏈古涧;但是catch還有try catch的作用,如果then()中邏輯代碼執(zhí)行失敗了花盐,并不會(huì)在控制臺(tái)拋出羡滑,而是直接走到catch捕獲)
Promise.all()方法的使用
- 本擴(kuò)展實(shí)現(xiàn)將多個(gè)異步操作合并到一個(gè)操作中菇爪,只有全部的請(qǐng)求都正確執(zhí)行,才會(huì)走到resolve中柒昏,否則走的都是reject凳宙,要么全部都有,要么全部都無(wú)
// 第一個(gè)promise操作
function fetch1() {
return new Promise((resolve, reject) => {
resolve('fetch1')
})
}
// 第二個(gè)promise操作
function fetch2() {
return new Promise((resolve, reject) => {
resolve('fetch2')
})
}
// 第三個(gè)promise操作
function fetch3() {
return new Promise((resolve, reject) => {
resolve('fetch3')
})
}
Promise([fetch1(), fetch2(), fetch3()]).then(
function(data) => {
console.log(data) // data是一個(gè)數(shù)組职祷,包含了全部返回的結(jié)果
},
function(err) {
console.log(err)
})
- 如果其中一個(gè)執(zhí)行錯(cuò)誤了氏涩,還是想繼續(xù)往下執(zhí)行咋辦嘞?
如果作為參數(shù)的Promise實(shí)例有梆,自己定義了catch方法削葱,那么它一旦被reject,并不會(huì)觸發(fā)Promise.all()的catch方法淳梦,而是走了Promise.all()方法的resolved
下面的例子析砸,既然有一個(gè)執(zhí)行錯(cuò)誤,也進(jìn)入resolve()中
let promiseArray = [fetch1(), fetch2(), fetch3()]
var handlePromise = Promise.all(promiseArray.map(function(promiseItem) {
return promiseItem.catch(function(err) {
return err
})
}))
handlePromise.then(function(values) {
console.log('all promise are resolved', values)
}).catch(function(reason) {
console.log('promise reject failed reason', reason)
})
Promise.race()
并列幾個(gè)異步操作爆袍,誰(shuí)先處理結(jié)束就以誰(shuí)為準(zhǔn)
如果一個(gè)Promise()狀態(tài)首繁,在幾秒之后還是沒(méi)有結(jié)束,那么就將他改為reject狀態(tài)
let readyPromise = new Promise((resolve, reject) => {
// ...成功狀態(tài)
resolve()
// ...失敗狀態(tài)
reject()
})
let timeout = new Promise((resolve, reject) => {
setTimeout(function(){
reject()
}, 5000)
})
Promise.race([readyPromise, timeout])
感謝您的view陨囊,留個(gè)贊再走唄
- 感謝瀏覽姑娘的文章弦疮,來(lái)自一個(gè)寫(xiě)前端的姑娘!