Promise 是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。它由社區最先提出和實現,ES6 將其寫進了語言標準,統一了用法,原生提供了Promise對象。es6
Promise 做爲一個對象,對象裏存儲一個狀態,這個狀態是能夠隨着內部的執行轉化的,爲如下三種狀態之一:等待態(Pending)、完成態(Fulfilled)、拒絕態(Rejected)。
一開始,咱們先設置好等狀態從 pending 變成 fulfilled 和 rejected 的預案(當成功後咱們作什麼,失敗時咱們作什麼)。
Promise 啓動以後,當知足成功的條件時咱們讓狀態從 pending 變成 fullfilled (執行 resolve);當知足失敗的條件,咱們讓狀態從 pending 變成 rejected(執行 reject)編程
Promise對象有如下兩個特色
(1)對象的狀態不受外界影響。
(2)一旦狀態改變,就不會再變,任什麼時候候均可以獲得這個結果。json
function Promise(){
return new Promise(function(resolve, reject) {
if (/* 異步操做成功 */){
resolve(value);
} else {
reject(error);
}
});
}
Promise構造函數接受一個函數做爲參數,該函數的兩個參數分別是resolve和reject。它們是兩個函數,由 JavaScript 引擎提供,不用本身部署。數組
promise.then(function(value) { // success
}, function(error) { // failure
}); //等價於:
promise.then(function(){ //success
}).catch(function(){ //failure
})
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
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
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' '報錯後的回調'
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 實例,包裝成一個新的 Promise 實例。函數
const p = Promise.race([p1, p2, p3]);
上面代碼中,只要p一、p二、p3之中有一個實例率先改變狀態,p的狀態就跟着改變。那個率先改變的 Promise 實例的返回值,就傳遞給p的回調函數。
Promise.race方法的參數與Promise.all方法同樣,若是不是 Promise 實例,就會先調用下面講到的Promise.resolve方法,將參數轉爲 Promise 實例,再進一步處理。post
有時須要將現有對象轉爲 Promise 對象,Promise.resolve方法就起到這個做用。spa
Promise.resolve('foo') // 等價於
new Promise(resolve => resolve('foo'))
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