Promise簡單來講就是一個容器,保存着某個將來纔會結束得事件(一般爲異步操做)得結果。從語法上來說,Promise是一個對象,能夠獲取異步操做得消息;Promise提供了統一 得API,各類異步操做均可以用一樣得方法進行處理。複製代碼
一、 Promise對象有兩大特色:數組
1)對象得狀態不受外界得影響。Promise對象表明一個異步操做。有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗)。只有異步操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態。 2)一旦狀態改變,就不會再變,任什麼時候候均可以獲得這個結果。 Promise 對象的狀態改變,只有兩種可能:從 pending 變爲 fulfilled 和從 pending 變爲 rejected 。只要這兩種狀況發生,狀態就凝固了,不會再變了,會一直保持這個結果,這時就稱爲 resolved(已定型)。若是改變已經發生了,你再對 Promise 對象添加回調函數,也會當即獲得這個結果。這與事件(Event)徹底不一樣,事件的特色是,若是你錯過了它,再去監聽,是得不到結果的。複製代碼
2.Promise得缺點:promise
1)沒法取消 Promise ,一旦新建它就會當即執行,沒法中途取消; 2)若是不設置回調函數, Promise 內部拋出的錯誤,不會反應到外部。 3)當處於 pending 狀態時,沒法得知目前進展到哪個階段(剛剛開始仍是即將完成)。複製代碼
3.Promise用法:異步
1)Promise對象是一個構造函數,用來生成Promise實例;ide
const KKBpromise = new Promise(function(resolve, reject) { // ... some code if (/* 異步操做成功 */){ resolve(value); } else { reject(error); } });複製代碼
Promise 構造函數接受一個函數做爲參數,該函數的兩個參數分別是resolve 和reject 。它們是兩個函數,由 JavaScript 引擎提供,不用本身部署。函數
resolve 函數的做用是,將 Promise對象的狀態從「未完成」變爲「成功」(即從 pending 變爲 resolved),在異步操做成功時調用,並將異步操做的結果,做爲參數傳遞出去;reject函數的做用是,將 Promise對象的狀態從「未完成」變爲「失敗」(即從 pending 變爲 rejected),在異步操做失敗時調用,並將異步操做報出的錯誤,做爲參數傳遞出去.code
Promise 實例生成之後,能夠用 then方法分別指定resolved狀態和 rejected狀態的回調函數。 舉個栗子:對象
KKBpromise.then(function(value) { // success }, function(error) { // failure });複製代碼
then 方法能夠接受兩個回調函數做爲參數。第一個回調函數是Promise對象的狀態變爲 resolved時調用,第二個回調函數是 Promise對象的狀態變爲rejected時調用。其中,第二個函數是可選的,不必定要提供。這兩個函數都接受 Promise 對象傳出的值做爲參數。事件
function pros(ms) { return new Promise((resolve, reject) => { setTimeout(resolve, ms, 'done'); }); } pros(100).then((value) => { console.log(value); });複製代碼
pros 方法返回一個 Promise 實例,表示一段時間之後纔會發生的結果。過了指定的時間( ms 參數)之後, Promise 實例的狀態變爲 resolved ,就會觸發 then 方法綁定的回調函數。ip
2)Promise新建後會當即執行。 舉例說明:部署
let promise = new Promise(function(resolve, reject) { console.log('Pro'); resolve(); }); promise.then(function() { console.log('resolved'); }); console.log('Hello Promise!'); // Pro // Hello Promise! // resolved複製代碼
Promise 新建後當即執行,因此首先輸出的是 Promise 。而後, then 方法指定的回調函數,將在當前腳本全部同步任務執行完纔會執行,因此 resolved 最後輸出。
有時候在調用 resolve 或 reject 之後,Promise 的使命就完成了,後繼操做應該放到 then 方法裏面,而不該該直接寫在 resolve 或 reject 的後面。因此,最好在它們前面加上 return 語句,這樣就不會有意外。
new Promise((resolve, reject) => { return resolve(1); // 後面的語句不會執行 console.log('接着執行'); })複製代碼
4.Promise經常使用得API:
1)Promise.all()這個方法返回一個新的promise對象,該promise對象在全部的promise對象都成功的時候纔會觸發成功,一旦有任何一個裏面的promise對象失敗則當即觸發該promise對象的失敗。這個新的promise對象在觸發成功狀態之後,會把一個包含全部promise返回值的數組做爲成功回調的返回值,順序跟參數的順序保持一致;若是這個新的promise對象觸發了失敗狀態,它會把第一個觸發失敗的promise對象的錯誤信息做爲它的失敗錯誤信息。Promise.all方法常被用於處理多個promise對象的狀態集合。
let kkb1 = new Promise((resolve, reject) => { resolve('成功了kkb1') }) let kkb2 = new Promise((resolve, reject) => { resolve('成功了kkb2') }) let kkb3 = Promse.reject('失敗') Promise.all([kkb1, kkb2]) .then((result) => { console.log(result) //['成功了kkb1', '成功了kkb2'] }) .catch((error) => { console.log(error) }) Promise.all([kkb1,kkb3,kkb2]) .then((result) => { console.log(result) }) .catch((error) => { console.log(error) // '失敗' })複製代碼
2)Promise.race的使用 race和all用法相似。Promse.race方法顧名思義就是賽跑的意思,意思就是說Promise.race([kkb1, kkb2, kkb3])裏面哪一個結果得到的快,就返回那個結果,無論結果自己是成功狀態仍是失敗狀態。
let kkb1 = new Promise((resolve, reject) => { setTimeout(() => { resolve('kkb1') },1000) }) let kkb2 = new Promise((resolve, reject) => { setTimeout(() => { reject('kkb2') }, 500) }) Promise.race([kkb1, kb2]) .then((result) => { console.log(result) }).catch((error) => { console.log(error) // 打印出kkb2 由於它快 })複製代碼