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(進行中)狀態時,無法得知目前進展到哪一個階段。