Promise介紹
promise是一個物件,從它可以獲取非同步操作的訊息。有all、race、reject、resolve這幾個方法,原型上有then、catch等方法。
Promise的兩個特點:
- 物件的狀態不受外界影響。Promise物件獲取的是非同步操作,有三種狀態:pending(進行中)、fulfilled(已成功)、reject(已失敗)。除了非同步操作的結果,其他操作都無法改變這個狀態。
- 一旦狀態改變,就不會再變。從pending變為fulfilled和從pending變為rejected狀態,只要處於fulfilled和rejected,狀態就不會再變。
狀態的缺點:
無法取消Promise,一旦新建它就會立即執行,無法中途取消。
如果不設定回撥函式,Promise內部丟擲錯誤,不會反應到外部。
當處於pending狀態時,無法得知目前進展到哪一階段。
使用語法:
let p = new Promise( (resolve,reject)=>{
//resolve 和reject是兩個函式
})
p.then(
()=>{}, // 傳入的resolve函式,resolve翻譯成中文是解決
()=>{} //傳入的reject函式,reject翻譯成中文是拒絕
).catch((reason,data)=>{
console.log("catch失敗執行回撥丟擲原因",reason)
})
then方法
then方法接收兩個引數作為引數,第一個引數是Promise執行成功時的回撥,第二個引數是Promise執行失敗的回撥,兩個函式只會有一個被呼叫。
通過.then新增的回撥函式,不論什麼時候,都會被呼叫,而且可以新增多個回撥函式,會一次按照順序並且獨立執行。
const p =new Promise((resolve,reject)=>{
resolve("成功")
})
p.then((res)=>{
console.log(res)//返回成功
},(err)=>{
console.log(err)
})
帶有多個回撥函式時
const p =new Promise((resolve,reject)=>{
resolve(1)
})
p.then((res1)=>{
console.log('res1',res1) // 1
return res1 * 2;
}).then((res2)=>{
console.log('res2',res2) //2
}).then((res3)=>{
console.log('res3',res3) //undefined
return Promise.resolve('resolve')
}).then(res4=>{
console.log('res4',res4) //resolve
})
catch用法
與Promise物件方法then並行的還有一個catch方法,用來捕獲異常的,與try...catch類似,
const p1 = new Promise((resolve,reject)=>{
var num = Math.random()*10 ;//隨機生成一個0-10的數字
console.log("num",num)
if(num > 5){
resolve('大於5')
}else{
reject("小於5")
}
})
p1.then(res=>{
console.log("res",res) // res 大於5
}).catch(err=>{
console.log("err",err) // err 小於5
})
all方法
all方法表示所有的非同步操作完成後才執行回撥,返回結果,返回的資料是個陣列,多個請求返回的資料組合。與then方法同級。
使用語法:Promise.all([ p,p1,p2.... ]).then()
使用例項如下:
const p1 = new Promise((resolve,reject)=>{
resolve({
name:'倩倩'
})
})
const p2 = new Promise((resolve,reject)=>{
resolve(['a','b'])
})
const p3 = new Promise((resolve,reject)=>{
resolve('二傻子')
})
Promise.all([p1,p2,p3]).then(res=>{
console.log(res)//[{name:'倩倩'}, ['a','b'], "二傻子"]
})
race方法
all是等所有的非同步操作都執行完成了再執行回撥,而race方法是相反的,只要有一個執行完成,不論結果是成功還是失敗,都開始執行回撥,其餘的不會再進入race的回撥。返回的資料取決於最早執行完畢返回的資料。
const p1 = new Promise((resolve,reject)=>{
resolve({
name:'倩倩'
})
})
const p2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve(['a','b'])
},1000)
})
const p3 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('二傻子')
},2000)
})
Promise.race([p1,p2,p3]).then(res=>{
console.log(res)//{name:'倩倩'}
})
為什麼使用Promise?
Promise的優點
- 指定回撥函式的方式更加靈活。
- 支援鏈式呼叫,可以解決回撥地獄問題。回撥地獄就是回撥函式巢狀呼叫,外部回撥函式非同步執行的結果是巢狀的回撥函式的執行條件。回撥地獄的缺點是不便於閱讀和異常處理。
Promise的缺點
- 無法取消Promise,一旦新建就會立即執行,無法暫停和取消。
- 如果不設定回撥函式,Promise內部丟擲的錯誤,不會反應到外部。
- 當處於pending(進行中)狀態時,無法得知目前進展到哪一個階段。