Promise對象

什麼是 Promise

Promise 是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。它由社區最先提出和實現,ES6 將其寫進了語言標準,統一了用法,原生提供了Promise對象。es6

Promise 做爲一個對象,對象裏存儲一個狀態,這個狀態是能夠隨着內部的執行轉化的,爲如下三種狀態之一:等待態(Pending)、完成態(Fulfilled)、拒絕態(Rejected)。
一開始,咱們先設置好等狀態從 pending 變成 fulfilled 和 rejected 的預案(當成功後咱們作什麼,失敗時咱們作什麼)。
Promise 啓動以後,當知足成功的條件時咱們讓狀態從 pending 變成 fullfilled (執行 resolve);當知足失敗的條件,咱們讓狀態從 pending 變成 rejected(執行 reject)編程

Promise對象有如下兩個特色
(1)對象的狀態不受外界影響。
(2)一旦狀態改變,就不會再變,任什麼時候候均可以獲得這個結果。json


基本用法

ES6 規定,Promise對象是一個構造函數,用來生成Promise實例。
function Promise(){
return new Promise(function(resolve, reject) {
  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
}); //等價於:
promise.then(function(){ //success
}).catch(function(){ //failure
})

 


做用

1. 連續調用回調:

  • 能夠採用連續的then鏈式操做來寫回調(這是由於返回值一直是新的Promise實例)。
  • 例子能夠看出來只要在第一個promise回調中添加resolve,以後的連續then就會默認執行。
setTimeout(function(){ left(function(){ setTimeout(function(){ left(function(){ setTimeout(function(){ left(); },2000); }); }, 2000); }); }, 2000); //咱們給left函數內容換成console.log(11);
 var p = new Promise((resolve,reject)=>{ setTimeout( resolve , 2000 ) }) .then( ()=>setTimeout( null, 2000 ) ) .then( ()=>setTimeout(function(){ console.log(11) },2000) ) //這樣在6秒鐘以後會打出11

 

點擊執行範例promise

 

2. 能夠在then中return出數據,而且這個數據會以參數的形式傳入下一個then。

var p = new Promise(function(resolve,reject){ var a=1 resolve(a); }).then(function(data){ console.log(data) return ++data; }).then( function(data){ console.log(data) } ) //打印出來的結果依次是: 1 2

 


catch()

  • catch是方法是.then(null, rejection)的別名,用於指定發生錯誤時的回調函數。(建議不要在then的第二個參數寫rejected狀態,老是使用catch)
  • catch()使回調報錯時不會卡死js而是會繼續往下執行。點擊執行範例
  • Promise 對象的錯誤具備「冒泡」性質,會一直向後傳遞,直到被捕獲爲止。也就是說,錯誤老是會被下一個catch語句捕獲。
getJSON('/post/1.json').then(function(post) { return getJSON(post.commentURL); }).then(function(comments) { }).catch(function(error) { // 處理 getJSON 和 前一個回調函數運行時發生的錯誤
}); var p = new Promise((resolve,reject)=> { n } ).then(()=>console.log('運行成功')) .catch( ()=>{a;console.log('報錯');} )//這裏咱們沒有定義a的值會報錯
  .catch( ()=> console.log('報錯2') ) .then( ()=>console.log('報錯後的回調') ) //運行結果是:'報錯2' '報錯後的回調'

 

  • 首先n沒有定義,因此第一層出錯。下一個then的‘運行成功’不會被打出來。而是會被下一個catch捕獲,
  • 第一個catch沒有定義a,因此報錯,console.log('報錯')沒辦法打出來,又被下一個catch捕獲:
  • 第二個catch沒有問題:打出‘報錯2’。運行成功傳給下一個then,打出'報錯後的回調'。
  • 無論是then或者catch返回的都是一個新的Promise實例!而每一個Primise實例都有最原始的Pending(進行中)到Resolve(已完成),或者Pending(進行中)到Reject(已失敗)的過程。

Promise.all()

Promise.all方法用於將多個 Promise 實例,包裝成一個新的 Promise 實例。異步

const p = Promise.all([p1, p2, p3]);

 

上面代碼中,Promise.all方法接受一個數組做爲參數,p一、p二、p3都是 Promise 實例,若是不是,就會先調用下面講到的Promise.resolve方法,將參數轉爲 Promise 實例,再進一步處理。(Promise.all方法的參數能夠不是數組,但必須具備 Iterator 接口,且返回的每一個成員都是 Promise 實例。)異步編程

Promise.race()

Promise.race方法一樣是將多個 Promise 實例,包裝成一個新的 Promise 實例。函數

const p = Promise.race([p1, p2, p3]);

 

上面代碼中,只要p一、p二、p3之中有一個實例率先改變狀態,p的狀態就跟着改變。那個率先改變的 Promise 實例的返回值,就傳遞給p的回調函數。
Promise.race方法的參數與Promise.all方法同樣,若是不是 Promise 實例,就會先調用下面講到的Promise.resolve方法,將參數轉爲 Promise 實例,再進一步處理。post

Promise.resolve()

有時須要將現有對象轉爲 Promise 對象,Promise.resolve方法就起到這個做用。spa

Promise.resolve('foo') // 等價於
new Promise(resolve => resolve('foo'))

 

  • 參數是一個 Promise 實例,Promise.resolve方法原封不動地返回這個實例。
  • 參數是一個then方法的對象,Promise.resolve方法會將這個對象轉爲 Promise 對象,而後就當即執行對象的then方法。
  • 參數不是具備then方法的對象,或根本就不是對象,Promise.resolve方法返回一個新的 Promise 對象,狀態爲resolved。
  • 不帶有任何參數,直接返回一個resolved狀態的 Promise 對象。

Promise.reject()

Promise.reject(reason)方法也會返回一個新的 Promise 實例,該實例的狀態爲rejected。
Promise.reject()方法的參數,會原封不動地做爲reject的理由,變成後續方法的參數。

const p = Promise.reject('出錯了'); // 等同於
const p = new Promise((resolve, reject) => reject('出錯了')) p.then(null, function (s) { console.log(s) }); // 出錯了

 

參考:
阮一峯ES6

相關文章
相關標籤/搜索