Promise
是異步編程的一種解決方案javascript
Promise
實例表明一個異步操做,從它能夠獲取異步操做的消息html
Promise
實例有三種狀態:java
Pending
:進行中es6
Resolved
:已完成編程
Rejected
:已失敗json
Promise
實例的狀態只能由 Pending->Resolved
, Pending->Rejected
。一旦Promise
實例的狀態發生改變,就不會再發生變化,任什麼時候候均可以獲得這個結果數組
爲何要使用Promise
:經過Promise
,能夠將一步操做以同步操做的流程表達出來,能夠避免層層嵌套的回調函數(回調地域),而且Promise
提供了統一的接口,使得控制異步操做更加容易promise
Promise
是一個構造函數,用來生成Promise
實例異步
var promise = new Promise(function(resolve, reject)){ // ... do something if (/*異步操做成果*/) { resolve(value) } else { /*異步操做失敗*/ reject(error) } }
Promise
構造函數接受一個函數做爲參數,該函數的兩個參數分別是resolve
和reject
。它們是兩個函數,由 JavaScript 引擎提供,不用本身部署。異步編程
resolve
函數的做用是,將Promise
實例的狀態從「未完成」變爲「成功」(即從 Pending
變爲 Resolved
),在異步操做成功時調用,並將異步操做的結果,做爲參數傳遞出去
reject
函數的做用是,將Promise
實例的狀態從「未完成」變爲「失敗」(即從 Pending
變爲 Rejected
),在異步操做失敗時調用,並將異步操做報出的錯誤,做爲參數傳遞出去**
Promise
實例生成之後,能夠用then
方法分別指定Resolved
狀態和Reject
狀態的回調函數。
var promise = new Promise(function(resolve, reject)){ // ... do something if (/*異步操做成果*/) { resolve(value) } else { /*異步操做失敗*/ reject(error) } } promise.then(function(value) { // success }, function(error) { // failure });
then
方法能夠接受兩個回調函數做爲參數。第一個回調函數是Promise
的狀態變爲Resolved
時調用,第二個回調函數是Promise
實例的狀態變爲Rejected
時調用。其中,第二個函數是可選的,不必定要提供。
這兩個函數都接受Promise
實例傳出的值做爲參數。(簡單地說就是:上面的promise
對象在處理異步操做的過程當中,若是調用了resolve
方法,則會將resolve
的參數傳遞給then
方法的第一個函數,若是調用了reject
方法,這會將reject
的參數傳遞給then
方法的第二個函數)
then
方法返回的是一個新的Promise
實例(注意,不是原來那個Promise
實例),所以能夠採用鏈式寫法,即then
方法後面在調用另外一個then
方法
上面的代碼使用then
方法,依次指定了兩個回調函數。第一個回調函數完成之後,會將返回結果做爲參數,傳入第二個回調函數。(其實是第一個then
方法返回了一個Promise
實例,在該實例中調用了resolve
方法,而json.post
則是做爲resolve
的參數)
上面代碼中,第一個then
方法指定的回調函數,返回的是另外一個Promise
實例,則第一個then
方法會直接將該Promise
實例返回
該方法是.then(undefined, onRejected)
的別名,用於指定發生錯誤時的回調函數。
promise.then(function(data) { console.log('success'); }).catch(function(error) { console.log('error', error); });
promise對象的錯誤,會一直向後傳遞,直到被捕獲。即錯誤總會被下一個catch所捕獲。then方法指定的回調函數,若拋出錯誤,也會被下一個catch捕獲。catch中也能拋錯,則須要後面的catch來捕獲。
sendRequest('test.html').then(function(data1) { //do something }).then(function (data2) { //do something }).catch(function (error) { //處理前面三個Promise產生的錯誤 });
該方法用於將多個Promise實例,包裝成一個新的Promise實例
// p1,p2,p3都是promise實例 var p = Promise.all([p1, p2, p3]);
新的Promise實例的狀態由三個promise實例共同決定
當三個promise實例的狀態都變爲fulfilled,p的狀態纔會變爲fulfilled,並將三個promise返回的結果,按照參數順序存入數組,傳給p的回調函數
當p1, p2, p3其中之一狀態變爲rejected,p的狀態也會變爲rejected,並把第一個被reject的promise的返回值,傳給p的回調函數
該方法用於將多個Promise實例,包裝成一個新的Promise實例
// p1,p2,p3都是promise實例 var p = Promise.race([p1, p2, p3]);
新的Promise實例的狀態由三個promise實例共同決定
當p1, p2, p3其中之一狀態發生改變(變爲fulfilled或者rejected),p的狀態也會隨之改變,並把第一個改變狀態的promise的返回值,傳給p的回調函數
Promise.resolve
方法的參數分爲四種狀況
參數是一個Promise實例
若是參數是Promise實例,那麼Promise.resolve將不作任何修改、原封不動地返回這個實例。
參數是一個thenable對象
let thenable = { then: function(resolve, reject) { resolve(42); } }; let p1 = Promise.resolve(thenable); p1.then(function(value) { console.log(value); // 42 });
Promise.resolve方法會將這個對象轉爲Promise對象,而後就當即執行thenable對象的then方法。
參數不是具備then方法的對象,或根本就不是對象
若是參數是一個原始值,或者是一個不具備then方法的對象,則Promise.resolve方法返回一個新的Promise對象,狀態爲Resolved。
Promise.resolve('Success'); /*******等同於*******/ new Promise(function (resolve) { resolve('Success'); });
不帶任何參數
直接返回一個Resolved狀態的Promise對象。
Promise.resolve('Success'); /*******等同於*******/ new Promise(function (resolve) { resolve(); });
Promise.reject(new Error('error')); /*******等同於*******/ new Promise(function (resolve, reject) { reject(new Error('error')); });
這段代碼會讓這個Promise對象當即進入rejected狀態,並將錯誤對象傳遞給then指定的onRejected回調函數。