一、什么是Promise
1张症、Promise的結(jié)構(gòu):
class Promise {
? ? constructor(exector) {
? ? ? ? function resolve() {}
? ? ? ? function reject() {}
? ? ? ? exector(ressolve, reject)
????}
? ? then() {}
}
2仓技、Premise的三個狀態(tài):
pending、fulfilled俗他、rejected(未決定脖捻、履行、拒絕)兆衅,同一時間只能存在一個狀態(tài)地沮,且狀態(tài)一旦改變就不能再變。Promise是一個構(gòu)造函數(shù)羡亩,Promise對象代表一項有兩種可能結(jié)果(成功或失斈σ伞)的任務(wù),它還持有多個回調(diào)夕春,出現(xiàn)不同結(jié)果時分別發(fā)出不同回調(diào)未荒。
-初始化,狀態(tài):pending
-當(dāng)調(diào)用resolve(成功)及志,狀態(tài):pending->fulfilled
-當(dāng)調(diào)用reject(失斊拧)寨腔,狀態(tài):pending->rejected
3、Promise的優(yōu)缺點
優(yōu)點:
1率寡、Promise分離了異步數(shù)據(jù)獲取和業(yè)務(wù)邏輯迫卢,有利于代碼復(fù)用;
2冶共、可以采用鏈?zhǔn)綄懛ǎ?br>3乾蛤、一旦Promise的值確定為fulfilled或rejected后,不可改變捅僵;
缺點:
代碼冗余家卖,語義不清。
二庙楚、為什么用Promise
1上荡、解決回調(diào)地獄
回調(diào)地獄:發(fā)送多個異步請求時,每個請求之間相互都有關(guān)聯(lián)馒闷,會出現(xiàn)第一個請求成功之后再做下一個請求的情況酪捡。我們這時候往往會用嵌套的方式解決這種情況,但是這會形成“回調(diào)地獄”纳账。如果處理的請求越多逛薇,那么回調(diào)就越深。出現(xiàn)的問題:
1疏虫、代碼邏輯順序與執(zhí)行順序不一致永罚,不利于閱讀和維護(hù);
2议薪、異步操作順序變更時尤蛮,需要大規(guī)模的代碼重構(gòu);
3斯议、回調(diào)函數(shù)基本都是匿名函數(shù),bug追蹤困難醇锚;
2哼御、解決異步
我們都知道js是單線程執(zhí)行代碼,導(dǎo)致js的很多操作都是異步操作的焊唬,以下是解決異步的幾種方式:
1恋昼、回調(diào)函數(shù)(定時器);
2赶促、事件監(jiān)聽液肌;
3、發(fā)布/訂閱鸥滨;
4嗦哆、Promise對象谤祖;(將執(zhí)行代碼和處理結(jié)果分開)
5、Generator老速;
6粥喜、ES7的async/await。
三橘券、怎么用Promise?
promise有幾種對象方法
1.then方法(異步執(zhí)行)
當(dāng)resolve(成功)/reject(失敗)的回調(diào)函數(shù)
//onFulfilled 是用來接收promise成功的值
//onRejected 是用來接收promise失敗的原因
promise.then(onFulfilled,onRejected)
2.resolve(成功)
? 調(diào)用onFulfilled
const promise = new Promise((resolve,reject)=>{
? ?resolve('fulfilled');//狀態(tài):pending=>fulfilled
})额湘;
?
promise.then(result =>{//onFulfilled調(diào)用
? ? console.log(result);//'fulfilled' ?
},result =>{//onRejected不調(diào)用
})
?
?
//注:resolve使用
Promise.resolve('hellow world')相當(dāng)于
//相當(dāng)于
const promise = new Promise(resolve=>{
? ?resolve('hellow world');
})
3.reject(失敗)
? 調(diào)用onRejected
const promise = new Promise((resolve,reject)=>{
? ? reject('rejected');//狀態(tài):pending=>rejected ? ?
});
?
promise.then(result =>{//onFulfilled不調(diào)用
},result =>{//onRejected調(diào)用
? ?console.log(result);//'rejected' ?
})
?
//注:reject使用
Promise.reject('err')相當(dāng)于
//相當(dāng)于
const promise = new Promise((resolve,reject)=>{
? ?reject('err');
});
4.catch
? 鏈?zhǔn)綄懛ㄖ锌梢圆东@前面then中發(fā)送的異常,這種寫法的好處在于先執(zhí)行promise操作,然后根據(jù)返回的結(jié)果(成功或失斉越ⅰ)來調(diào)用onFulfilled(或者onRrejected)函數(shù)锋华。
promise.then(onFulfilled).catch(onRrejected);
5.all
? Promise.all接收一個promise對象數(shù)組為參數(shù),處理并行異步操作會用到箭窜,但是需要全部為resolve才能調(diào)用毯焕。這種情況是幾個任務(wù)可以并行執(zhí)行
const promise1= new Promise((resolve,reject)=>{
? ?resolve('promise1');
});
const promise2= new Promise((resolve,reject)=>{
? ?resolve('promise2');
});
const promise3= new Promise((resolve,reject)=>{
? ?resolve('promise3');
});
Promise.all([promise1, promise2, promise3]).then(data => {
? ?console.log(data);
? ?// ['promise1', 'promise2', 'promise3'] 結(jié)果順序和promise實例數(shù)組順序是一致的
}, err => {
? ?console.log(err);
});
可以從一個promise對象派生出新的promise對象,我們可以要求代表著并行任務(wù)的兩個promise對象合并成一個promise對象绽快,由后者負(fù)責(zé)通知前面的那些任務(wù)都已完成芥丧。也可以要求代表著任務(wù)系列中首要任務(wù)的Promise對象派生出一個能代表任務(wù)系列中末任務(wù)的Promise對象,這樣后者就能知道這一系列的任務(wù)是否均已完成坊罢。
6.race
? Promise.race接收一個promise對象數(shù)組為參數(shù)续担,只要有一個promise對象進(jìn)入Fulfilled或者Rejected狀態(tài)的話,就會進(jìn)行后面的處理活孩。這可以解決多個異步任務(wù)的容錯
function racePromise(time){
? ?return new Promise((resolve,reject)=>{
? ? ? ?setTimeout(()=>{
? ? ? ? ? ?resolve(time);
? ? ?? },time)
?? })
}
var startDate = Date.now();
Promise.race([
? ?racePromise(5),
? ?racePromise(50),
? ?racePromise(500),
]).then(function(values){
? ?console.log(values);5
})
參考文章:https://blog.csdn.net/endeavor_no1/article/details/83416949