Promise的興起,是因為異步方法調用中,往往會出現(xiàn)回調函數(shù)一環(huán)扣一環(huán)的情況基显。這種情況導致了回調金字塔問題的出現(xiàn)。不僅代碼寫起來費勁又不美觀善炫,而且問題復雜的時候撩幽,閱讀代碼的人也難以理解。
例如:
db.save(data, function(data){
// do something...
db.save(data1, function(data){
// do something...
db.save(data2, function(data){
// do something...
done(data3); // 返回數(shù)據(jù)
})
});
});
- 假設有一個數(shù)據(jù)庫保存操作箩艺,一次請求需要在三個表中保存三次數(shù)據(jù)窜醉。那么我們的代碼就跟上面的代碼相似了。這時候假設在第二個db.save出了問題怎么辦艺谆?基于這個考慮榨惰,我們又需要在每一層回調中使用類似try...catch這樣的邏輯。
- 另外一個缺點就是静汤,假設我們的三次保存之間并沒有前后依賴關系琅催,我們仍然需要等待前面的函數(shù)執(zhí)行完畢, 才能執(zhí)行下一步,而無法三個保存并行虫给,之后返回一個三個保存過后需要的結果藤抡。(或者說實現(xiàn)起來需要技巧)
ES6 Promise
Promise對象狀態(tài)
它三個狀態(tài):
pending(執(zhí)行中)
fulfilled(成功)
-
reject(拒絕)
狀態(tài)轉換關系為:pending->fulfilled,pending->rejected抹估。
Promise的長相就像這樣子:
var promise = new Promise(function func(resolve, reject){
// do somthing, maybe async
if (success){
return resolve(data);
} else {
return reject(data);
}
});
promise.then(function(data){
// do something... e.g
console.log(data);
}, function(err){
// deal the err.
})
這里的變量promise是Promise這個對象的實例缠黍。
promise對象在創(chuàng)建的時候會執(zhí)行func函數(shù)中的邏輯。resolve這個回調會將值傳遞到一個特殊的地方药蜻。這個特殊的地方在哪呢瓷式?就是下面代碼中的then,我們使用then中的回調函數(shù)來處理resolve后的結果语泽。比如上面的代碼中贸典,我們將值簡單的輸出到控制臺。如果有錯誤湿弦,則reject到then的第二個回調函數(shù)中瓤漏,對錯誤進行處理腾夯。
Promise數(shù)據(jù)流動
promise的then方法依然能夠返回一個Promise對象颊埃,這樣我們就又能用下一個then來做一樣的處理。
第一個then中的兩個回調函數(shù)決定第一個then返回的是一個什么樣的Promise對象蝶俱。
假設第一個then的第一個回調沒有返回一個Promise對象班利,那么第二個then的調用者還是原來的Promise對象,只不過其resolve的值變成了第一個then中第一個回調函數(shù)的返回值榨呆。
假設第一個then的第一個回調函數(shù)返回了一個Promise對象罗标,那么第二個then的調用者變成了這個新的Promise對象,第二個then等待這個新的Promise對象resolve或者reject之后執(zhí)行回調。
-
Promise對象還有一個方法catch闯割,這個方法接受一個回調函數(shù)來處理錯誤彻消。
promise.catch(function(err){ // deal the err. })
控制并發(fā)的Promise
Promise有一個”靜態(tài)方法”——Promise.all(注意并非是promise.prototype), 這個方法接受一個元素是Promise對象的數(shù)組宙拉。
- 這個方法也返回一個Promise對象宾尚,如果數(shù)組中所有的Promise對象都resolve了,那么這些resolve的值將作為一個數(shù)組作為Promise.all這個方法的返回值的(Promise對象)的resolve值谢澈,之后可以被then方法處理煌贴。如果數(shù)組中任意的Promise被reject,那么該reject的值就是Promise.all方法的返回值的reject值.
還有一個和Promise.all相類似的方法Promise.race,它同樣接收一個數(shù)組锥忿,只不過它只接受第一個被resolve的值牛郑。