ES6系列之promise

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)      // 失敗了,打出 '失敗'
})
相關文章
相關標籤/搜索