ES6 原生提供了 Promise 對象。編程
所謂 Promise,就是一個對象,用來傳遞異步操做的消息。它表明了某個將來纔會知道結果的事件(一般是一個異步操做),而且這個事件提供統一的 API,可供進一步處理。 Promise是異步編程的一種解決方案api
基本的 api數組
Promise.resolve()promise
Promise.reject()異步
Promise.prototype.then()異步編程
Promise.prototype.catch()函數
Promise.all() // 全部的完成ui
var p = Promise.all([p1,p2,p3]);spa
Promise.race() // 競速,完成一個便可prototype
Promise的內部實現是一個狀態機。 Promise有三種狀態:pending,resolved,rejected。 當Promise剛建立完成時,處於pending狀態; 當Promise中的函數參數執行了resolve後,Promise由pending狀態變成resolved狀態; 若是在Promise的函數參數中執行的不是resolve方法,而是reject方法,那麼Promise會由pending狀態變成rejected狀態。
var p = new Promise(function(resolve, reject){
console.log("create a promise");
resolve("success");
});
console.log("after new Promise");
p.then(function(value){
console.log(value);
});
複製代碼
輸出結果
一、"create a promise"
二、"after new Promise"
三、"success"
var p1 = new Promise(function(resolve, reject){
resolve("success1");
resolve("success2");
});
var p2 = new Promise(function(resolve, reject){
resolve("success");
reject("reject");
});
p1.then(function(value){
console.log(value);
});
p2.then(function(value){
console.log(value);
});
複製代碼
Promise狀態的一旦變成resolved或rejected時,Promise的狀態和值就固定下來了,不論你後續再怎麼調用resolve或reject方法,都不能改變它的狀態和值。
var p = new Promise(function(resolve, reject){
resolve("success");
});
p.then(function(value){
console.log(value);
});
console.log("which one is called first ?");
複製代碼
var p = new Promise(function(resolve, reject){
resolve(1);
});
p.then(function(value){ //第一個then
console.log(value);
return value*2;
}).then(function(value){ //第二個then
console.log(value);
}).then(function(value){ //第三個then
console.log(value);
return Promise.resolve('resolve');
}).then(function(value){ //第四個then
console.log(value);
return Promise.reject('reject');
}).then(function(value){ //第五個then
console.log('resolve: '+ value);
}, function(err){
console.log('reject: ' + err);
})
複製代碼
結果輸出
1
2
undefined
"resolve"
"reject: reject"
Promise對象的then方法返回一個新的Promise對象,所以能夠經過鏈式調用then方法。then方法接收兩個函數做爲參數,第一個參數是Promise執行成功時的回調,第二個參數是Promise執行失敗時的回調。兩個函數只會有一個被調用,函數的返回值將被用做建立then返回的Promise對象。這兩個參數的返回值能夠是如下三種狀況中的一種:
return 一個同步的值 ,或者 undefined(當沒有返回一個有效值時,默認返回undefined),then方法將返回一個resolved狀態的Promise對象,Promise對象的值就是這個返回值。 return 另外一個 Promise,then方法將根據這個Promise的狀態和值建立一個新的Promise對象返回。 throw 一個同步異常,then方法將返回一個rejected狀態的Promise, 值是該異常。
var p1 = new Promise( function(resolve,reject){
foo.bar();
resolve( 1 );
});
p1.then(
function(value){
console.log('p1 then value: ' + value);
},
function(err){
console.log('p1 then err: ' + err);
}
).then(
function(value){
console.log('p1 then then value: '+value);
},
function(err){
console.log('p1 then then err: ' + err);
}
);
複製代碼
var p2 = new Promise(function(resolve,reject){
resolve( 2 );
});
p2.then(
function(value){
console.log('p2 then value: ' + value);
foo.bar();
},
function(err){
console.log('p2 then err: ' + err);
}
).then(
function(value){
console.log('p2 then then value: ' + value);
},
function(err){
console.log('p2 then then err: ' + err);
return 1;
}
).then(
function(value){
console.log('p2 then then then value: ' + value);
},
function(err){
console.log('p2 then then then err: ' + err);
}
);
複製代碼
p1 then err: ReferenceError: foo is not defined
p2 then value: 2
p1 then then value: undefined
p2 then then err: ReferenceError: foo is not defined
p2 then then then value: 1 Promise中的異常由then參數中第二個回調函數(Promise執行失敗的回調)處理,異常信息將做爲Promise的值。異常一旦獲得處理,then返回的後續Promise對象將恢復正常,並會被Promise執行成功的回調函數處理。另外,須要注意p一、p2 多級then的回調函數是交替執行的 ,這正是由Promise then回調的異步性決定的。
then()方法使Promise原型鏈上的方法,它包含兩個參數方法,分別是已成功resolved的回調和已失敗rejected的回調
.catch()的做用是捕獲Promise的錯誤,與then()的rejected回調做用幾乎一致。可是因爲Promise的拋錯具備冒泡性質,可以不斷傳遞,這樣就可以在下一個catch()中統一處理這些錯誤。同時catch()也可以捕獲then()中拋出的錯誤,因此建議不要使用then()的rejected回調,而是統一使用catch()來處理錯誤
一樣,catch()中也能夠拋出錯誤,因爲拋出的錯誤會在下一個catch中被捕獲處理,所以能夠再添加catch()
使用rejects()方法改變狀態和拋出錯誤 throw new Error() 的做用是相同的
當狀態已經改變爲resolved後,即便拋出錯誤,也不會觸發then()的錯誤回調或者catch()方法
then() 和 catch() 都會返回一個新的Promise對象,能夠鏈式調用
用來包裝一個現有對象,將其轉變爲Promise對象,但Promise.resolve()會根據參數狀況返回不一樣的Promise:
參數是Promise:原樣返回 參數帶有then方法:轉換爲Promise後當即執行then方法 參數不帶then方法、不是對象或沒有參數:返回resolved狀態的Promise
Promise.reject()會直接返回rejected狀態的Promise
參數爲Promise對象數組,若是有不是Promise的對象,將會先經過上面的Promise.resolve()方法轉換
var promise = Promise.all( [p1, p2, p3] )
promise.then(
...
).catch(
...
)
複製代碼
當p一、p二、p3的狀態都變成resolved時,promise纔會變成resolved,並調用then()的已完成回調,但只要有一個變成rejected狀態,promise就會馬上變成rejected狀態
var promise = Promise.race( [p1, p2, p3] )
promise.then(
...
).catch(
...
)
複製代碼
「競速」方法,參數與Promise.all()相同,不一樣的是,參數中的p一、p二、p3只要有一個改變狀態,promise就會馬上變成相同的狀態並執行對於的回調
Promise.done() 的用法相似 .then() ,能夠提供resolved和rejected方法,也能夠不提供任何參數,它的主要做用是在回調鏈的尾端捕捉前面沒有被 .catch() 捕捉到的錯誤
Promise. finally() 接受一個方法做爲參數,這個方法無論promise最終的狀態是怎樣,都必定會被執行