ES6新增語(yǔ)法—Promise詳解
Promise介紹
promise是一個(gè)對(duì)象,從它可以獲取異步操作的消息。有all、race、reject、resolve這幾個(gè)方法,原型上有then、catch等方法。
Promise的兩個(gè)特點(diǎn):
- 對(duì)象的狀態(tài)不受外界影響。Promise對(duì)象獲取的是異步操作,有三種狀態(tài):pending(進(jìn)行中)、fulfilled(已成功)、reject(已失敗)。除了異步操作的結(jié)果,其他操作都無法改變這個(gè)狀態(tài)。
- 一旦狀態(tài)改變,就不會(huì)再變。從pending變?yōu)閒ulfilled和從pending變?yōu)閞ejected狀態(tài),只要處于fulfilled和rejected,狀態(tài)就不會(huì)再變。
狀態(tài)的缺點(diǎn):
無法取消Promise,一旦新建它就會(huì)立即執(zhí)行,無法中途取消。
如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出錯(cuò)誤,不會(huì)反應(yīng)到外部。
當(dāng)處于pending狀態(tài)時(shí),無法得知目前進(jìn)展到哪一階段。
使用語(yǔ)法:
- let p = new Promise( (resolve,reject)=>{
- //resolve 和reject是兩個(gè)函數(shù)
- })
- p.then(
- ()=>{}, // 傳入的resolve函數(shù),resolve翻譯成中文是解決
- ()=>{} //傳入的reject函數(shù),reject翻譯成中文是拒絕
- ).catch((reason,data)=>{
- console.log("catch失敗執(zhí)行回調(diào)拋出原因",reason)
- })
then方法
then方法接收兩個(gè)參數(shù)作為參數(shù),第一個(gè)參數(shù)是Promise執(zhí)行成功時(shí)的回調(diào),第二個(gè)參數(shù)是Promise執(zhí)行失敗的回調(diào),兩個(gè)函數(shù)只會(huì)有一個(gè)被調(diào)用。
通過.then添加的回調(diào)函數(shù),不論什么時(shí)候,都會(huì)被調(diào)用,而且可以添加多個(gè)回調(diào)函數(shù),會(huì)一次按照順序并且獨(dú)立運(yùn)行。
- const p =new Promise((resolve,reject)=>{
- resolve("成功")
- })
- p.then((res)=>{
- console.log(res)//返回成功
- },(err)=>{
- console.log(err)
- })
帶有多個(gè)回調(diào)函數(shù)時(shí)
- 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對(duì)象方法then并行的還有一個(gè)catch方法,用來捕獲異常的,與try...catch類似,
- const p1 = new Promise((resolve,reject)=>{
- var num = Math.random()*10 ;//隨機(jī)生成一個(gè)0-10的數(shù)字
- 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方法表示所有的異步操作完成后才執(zhí)行回調(diào),返回結(jié)果,返回的數(shù)據(jù)是個(gè)數(shù)組,多個(gè)請(qǐng)求返回的數(shù)據(jù)組合。與then方法同級(jí)。
使用語(yǔ)法:
- Promise.all([ p,p1,p2.... ]).then()
使用實(shí)例如下:
- 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是等所有的異步操作都執(zhí)行完成了再執(zhí)行回調(diào),而race方法是相反的,只要有一個(gè)執(zhí)行完成,不論結(jié)果是成功還是失敗,都開始執(zhí)行回調(diào),其余的不會(huì)再進(jìn)入race的回調(diào)。返回的數(shù)據(jù)取決于最早執(zhí)行完畢返回的數(shù)據(jù)。
- 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的優(yōu)點(diǎn)
- 指定回調(diào)函數(shù)的方式更加靈活。
- 支持鏈?zhǔn)秸{(diào)用,可以解決回調(diào)地獄問題?;卣{(diào)地獄就是回調(diào)函數(shù)嵌套調(diào)用,外部回調(diào)函數(shù)異步執(zhí)行的結(jié)果是嵌套的回調(diào)函數(shù)的執(zhí)行條件?;卣{(diào)地獄的缺點(diǎn)是不便于閱讀和異常處理。
Promise的缺點(diǎn)
- 無法取消Promise,一旦新建就會(huì)立即執(zhí)行,無法暫停和取消。
- 如果不設(shè)置回調(diào)函數(shù),Promise內(nèi)部拋出的錯(cuò)誤,不會(huì)反應(yīng)到外部。
- 當(dāng)處于pending(進(jìn)行中)狀態(tài)時(shí),無法得知目前進(jìn)展到哪一個(gè)階段。