ES6新增語法—Promise詳解
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(進行中)狀態時,無法得知目前進展到哪一個階段。