第一部分、什麼是promise ?
promise是es6中提供的乙個非同步程式設計的解決方案,promise本身是乙個建構函式
typeof promise //function
一般情況下 我們在開發中會使用 new promise() 呼叫建構函式,建立乙個新的promise物件, promise物件有兩個特點
1、物件的狀態不受外界影響。promise
物件是乙個非同步操作,有三種狀態:pending
(進行中)、fulfilled
(已成功)和rejected
(已失敗)。
只有非同步操作的結果,可以決定promise是哪一種狀態,任何其他操作都無法改變這個狀態
2、
一旦promise狀態改變,就不會再有變化,任何時候都可以得到這個結果。promise物件的狀態改變,只有兩種可能:從pending變為fulfilled 或者 從pending變為rejected。只要這兩種情況發生,狀態就不會再變了,會一直保持這個結果,這時就稱為 resolved(已定型)。如果改變已經發生了,你再對promise物件新增**函式,也會立即得到這個結果。這與事件(event)不同,事件的特點是,如果你錯過了它,再去監聽,是得不到結果的
使用promise的好處,就是在處理非同步程式時,將非同步操作佇列化,按照期望的順序執行,返回符合預期的結果,這樣即使是多重非同步操作,也可以方便的使用promise進行鏈式呼叫
3、promise
也有一些缺點。
首先,無法取消promise
,一旦新建它就會立即執行,無法中途取消。其次,如果不設定**函式,promise
內部丟擲的錯誤,不會反應到外部。第三,當處於pending
狀態時,無法得知目前進展到哪乙個階段(剛剛開始還是即將完成)
第二部分、循序漸進的介紹promise的用法
1、最簡單的用法
const p = new promise((resolve, reject) =>, 3000)})//
建立這個promise之後, 3秒後 會控制台輸出1234,並且3秒後得到了乙個結果,非同步程式返回了1234這個結果,那麼
p.then((res) =>)
//控制台會輸出1234 ,promise的then方法 會再次返回乙個promise,不過值預設undefined
p.then((res) =>).then((res)=>)
//1234, undefined
2、reject的用法
const p2 = new promise((resolve, reject)=>, 3000)})p2.then(res=>).
catch(res=>)
//3秒之後 輸出錯誤 1024
3、all的用法, 多個非同步操作進行陣列形式的返回值處理,當所有的非同步都resolve時,可以執行then操作,當其中乙個或多個reject時,所有的非同步都會停止呼叫,直接返回最早發生錯誤的那個結果
const pa = new promise((resolve, reject)=>,3000)})const pb = new promise((resolve, reject)=>,4000)
})const pc = new promise((resolve, reject)=>,5000)
})const pd = new promise((resolve, reject)=>,5000)
})promise.all([pa, pb, pc]).then((res)=>)
//3秒後 pa 4秒後pb 5秒後 pc pd 然後輸出成功pa,pb,pc
promise.all([pa, pb, pd]).then((res)=>).
catch(err=>)
//輸出失敗pd
4、race的用法, 語法和all()一樣,但是返回值有所不同,race根據傳入的多個promise例項,只要有乙個例項resolve或者reject,就只返回該結果,其他例項不再執行,也就是說多個非同步程式,只返回響應最快的那個非同步程式,不論成功或者失敗,就把最快響應的返回值返回,後面的非同步程式不再執行
const pa = new promise((resolve, reject)=>,3000)})const pb = new promise((resolve, reject)=>,4000)
})const pc = new promise((resolve, reject)=>,5000)
})const pd = new promise((resolve, reject)=>,5000)
})const pe = new promise((resolve, reject)=>,2000)
})const pf = new promise((resolve, reject)=>,2000)
})promise.race([pa, pe, pf]).then(res=>).
catch(res=>)
promise.race([pd, pe]).then().
catch(res=>)
//2秒後 輸出 失敗 + pe
//2秒後 輸出 失敗 + pe
5、resolve方法,
promise的resolve方法,用於將非promise型別的物件,轉為promise物件,這樣就可以呼叫promise原型物件上的方法了
promise.resolve(x)上面的寫法等價於
new promise(resolve => )
resolve的引數分為幾種不同的情況:
(1)沒有引數,如果沒有引數,這直接返回乙個resolved狀態的promise物件
const p =promise.resolve()相當於
const p = new promise(resolve =>)
p.then(res=>)
//輸出 undefined
(2) 引數是乙個不具有then方法的物件,或者是乙個基數資料型別的值,則promise.resolve
方法返回乙個新的 promise 物件,狀態為resolved,值為指定值
const p = promise.resolve('pro')p.then((x) =>)
//輸出 'pro'
(3) 引數是乙個具有then方法的物件,promise.resolve
方法會將這個物件轉為 promise 物件,然後就立即執行thenable
物件的then
方法。
const obj =}const p =promise.resolve(obj)
p.then((res) =>)
//輸出 100
(4)引數是乙個promise物件,那麼將原封不動的返回這個promise物件
6、reject方法
reject與resolve方法基本類似,但是要注意一種情況,就是當引數是乙個thenable物件時
const thenable =};promise.reject(thenable)
.catch(e =>)
//true
7、finally方法,finally
方法用於指定不管 promise 物件最後狀態如何,都會執行的操作。該方法是 es2018 引入標準的。
finally
方法的**函式不接受任何引數,這意味著沒有辦法知道,前面的 promise 狀態到底是fulfilled
還是rejected
。這表明,finally
方法裡面的操作,應該是與狀態無關的,不依賴於 promise 的執行結果。finally
本質上是then
方法的特例。
const p = new promise((resolve, reject)=>else
},3000)
})p.then(res=>).
catch(err=>).
finally(()=>)
//無論是resolve 還是 reject都會 執行 finally
//finally的 polyfill也很簡單
promise.prototype.
finally = function
(callback) )
);};
ES6關於Promise的用法
含義 promise 物件用於乙個非同步操作的最終完成 或失敗 及其結果值的表示。簡單點說,它就是用於處理非同步操作的,非同步處理成功了就執行成功的操作,非同步處理失敗了就捕獲錯誤或者停止後續操作。new promise executor function resolve,reject else 我...
ES6中的Promise物件
列印出promise,我們能看出promise是乙個建構函式 那什麼是promise?promise是非同步程式設計的一種解決方案,它有三種狀態,promise執行完成後,只會有成功和失敗的狀態,並且不可被更改 pending 就緒狀態 resolved 成功狀態 pending 就緒狀態 reje...
談談 ES6 的 Promise 物件
ajax 如果幾個非同步操作之間並沒有前後順序之分 例如不需要前乙個請求的結果作為後乙個請求的引數 時,同樣需要等待上乙個操作完成再實行下乙個操作。function helloworld ready else helloworld true then function message functio...