1.promise是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。
promise對象有如下兩個特色:
1)對象的狀態不受影響。Promise對象表明一個異步操做,有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗)。
2)一旦狀態改變,就不會再變,任什麼時候候均可以獲得這個結果。Promise對象的狀態改變,只有兩種可能:從pending變爲fulfilled和從pending變爲rejected。只要這兩種狀況發生,狀態就凝固了,不會再變了,會一直保持這個結果,這時就成爲resolved(已定型)編程
Promise也會有一些缺點。
首先,沒法取消Promise,一旦新建它就會當即執行,沒法中途取消。
其次,若是不設置回調函數,Promise內部拋出的錯誤,不會反應到外部。
第三,當處於pending狀態時,沒法得知目前進展到哪個階段。json
2.基本用法promise
const promise = 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),在異步操做失敗時調用,並將異步操做報出的錯誤,做爲參數傳遞出去。
Promise實例生成之後,能夠用then方法分別指定resolved狀態和rejected狀態的回調函數。異步
promise.then(function(value) { // success }, function(error) { // failure });
3.Promise.prototype.then()
then方法返回的是一個新的Promise實例。所以能夠採用鏈式寫法,即then方法後面再調用另外一個then方法。異步編程
getJSON("/posts.json").then(function(json) { return json.post; }).then(function(post) { // ... });
4.Promise.prototype.catch()
Promise.prototype.catch方法是.then(null,rejection)的別名,用於指定發生錯誤的回調函數。
上面代碼中,getJSON方法返回一個 Promise 對象,若是該對象狀態變爲resolved,則會調用then方法指定的回調函數;若是異步操做拋出錯誤,狀態就會變爲rejected,就會調用catch方法指定的回調函數,處理這個錯誤。另外,then方法指定的回調函數,若是運行中拋出錯誤,也會被catch方法捕獲。函數
Promise 對象的錯誤具備「冒泡」性質,會一直向後傳遞,直到被捕獲爲止。也就是說,錯誤老是會被下一個catch語句捕獲。
通常來講,不要在then方法裏面定義 Reject 狀態的回調函數(即then的第二個參數),老是使用catch方法。post
5.Promise.prototype.finally()
finally方法用於指定無論Promise對象最後狀態如何,都會執行的操做。prototype
6.Promise.all()
Promise.all方法用於將多個Promise實例,包裝成一個新的Promise實例。code
const databasePromise = connectDatabase(); const booksPromise = databasePromise .then(findAllBooks); const userPromise = databasePromise .then(getCurrentUser); Promise.all([ booksPromise, userPromise ]) .then(([books, user]) => pickTopRecommentations(books, user));
上面代碼中,booksPromise和userPromise是兩個異步操做,只有等到它們的結果都返回了,纔會觸發pickTopRecommentations這個回調函數。
注意,若是做爲參數的 Promise 實例,本身定義了catch方法,那麼它一旦被rejected,並不會觸發Promise.all()的catch方法。對象
let p1 = new Promise((resolve, reject) => { resolve('成功了') }) let p2 = new Promise((resolve, reject) => { resolve('success') }) let p3 = Promise.reject('失敗') Promise.all([p1, p2]).then((result) => { console.log(result) //['成功了', 'success'] }).catch((error) => { console.log(error) }) Promise.all([p1,p3,p2]).then((result) => { console.log(result) }).catch((error) => { console.log(error) // 失敗了,打出 '失敗' })