JS中的promise
promise對象用于表示一個異步操作的最終完成 (或失敗),及其結(jié)果值。屬于ES6語法中的內(nèi)容。
用于處理異步問題杈曲。
單線程是js的痛點驰凛,因此,如何解決單線程問題担扑,引用了異步的概念恰响,用異步來模擬多線程的用法。其中ajax是典型的利用異步加載數(shù)據(jù)魁亦,實現(xiàn)數(shù)據(jù)刷新的案例渔隶。
但在處理多個有相互依賴關(guān)系的異步操作時,便會出現(xiàn)回調(diào)地獄洁奈。
//以ajax距離---回調(diào)地獄
ajax(function(){
ajax(function(){
ajax(function(){
ajax(function(){
})
})
})
})
極大的影響程序的運行间唉,占用內(nèi)存。
因此利术,promise提供了很好的解決方式呈野,用于解決這些問題。
promise對象是一個代理對象(代理一個值)印叁,被代理的值在promise對象創(chuàng)建時可能是未知的被冒。它允許為異步操作的成功和失敗分別綁定相應(yīng)的處理方法,但不是立即返回執(zhí)行結(jié)果轮蜕,而是返回成功或失敗的狀態(tài)
昨悼。
語法new Promise( function(resolve, reject) {...}
promise有以下幾種狀態(tài):
- pending:初始狀態(tài),既不是成功跃洛,也不是失敗
- fulfilled:意味著操作成功
- rejected:意味著操作失敗
then()方法
在初始狀態(tài)時率触,promise對象可能變成fulfilled狀態(tài)并返回一個相應(yīng)的狀態(tài)處理方法,也可能變成rejected狀態(tài)并返回一個失敗信息汇竭。當(dāng)其中一種情況出現(xiàn)時葱蝗,promise狀態(tài)便不會改變,而是成為其中的一種狀態(tài)细燎,promise的then
方法綁定的處理方法handlers
便會被調(diào)用两曼。其中then
方法中綁定了兩個參數(shù):onfulfilled 和 onrejected,當(dāng)返回的狀態(tài)是fulfilled玻驻,調(diào)用onfulfilled方法悼凑,當(dāng)返回的狀態(tài)是rejected,調(diào)用onrejected方法击狮。
在promise的語法中佛析,new Promise( function(resolve, reject) {...}
當(dāng)promise被new創(chuàng)建時,會有resolve
, reject
這兩個參數(shù)彪蓬。其中當(dāng)異步任務(wù)成功并返回結(jié)果值是,會調(diào)用resolve函數(shù)捺萌;而當(dāng)異步任務(wù)失敗并返回失敗原因時档冬,會調(diào)用reject函數(shù)膘茎。
以ajax為例:
function ajaxGet(url,data){
data = data || {};
var str = "";
for(var i in data){
str = str + i+"="+data[i]+"&";
}
var d = new Date();
url = url + "?" + str + "__htnt="+d.getTime();
var p = new Promise((resolve,reject)=>{
var xhr = new XMLHttpRequest();
xhr.open("get",url,true);
xhr.onreadystatechange = function(){
if(xhr.readyState == 4 && xhr.status == 200){
resolve(xhr.responseText);
}else if(xhr.readyState == 4 && xhr.status != 200){
reject(xhr.status)
}
}
xhr.send();
});
return p;
}
在這個ajax-get封裝中,當(dāng)傳輸成功時酷誓,則將成功后得到數(shù)據(jù)返回作為參數(shù)返回給resolve函數(shù)披坏;當(dāng)失敗時,將失敗狀態(tài)作為參數(shù)返回給reject函數(shù)盐数。
假設(shè)此時它有返回值棒拂,且 var p = ajaxGet(...)
p.then(function(data){
console.log("成功");
console.log('返回值為:',data);
},function(data){
console.log("失敗");
console.log("錯誤代碼:",data);
})
還可以在p.then(function(){})再加上.then(function(){}).then(function(){})
p.then(function(){
}).then(function(){
}).then(function(){
})...
可以將第一次異步得到的數(shù)據(jù)傳到第一個then中,然后在將從第一個then中處理的數(shù)據(jù)進行第二次異步操作玫氢,并傳遞結(jié)果帚屉,依次往下傳遞。
catch()方法
添加一個拒絕(rejection)回調(diào)到當(dāng)前 promise, 返回一個新的promise漾峡。只用來捕獲失敗狀態(tài)攻旦。
finally()方法 --ES2018
finally
添加一個事件處理回調(diào)與當(dāng)前promise對象,并且在原promise對象解析完畢后生逸,返回一個新的promise對象。無論結(jié)果是fulfilled或者是rejected,都會執(zhí)行指定的回調(diào)函數(shù)荧飞。避免了同樣的語句需要在then()和catch()中各寫一次的情況毫捣。
all()方法
假設(shè)情況如下:
var p1 = ajaxGet(...);
var p2 = ajaxGet(...);
var p3 = ajaxGet(...);
Promise.all([p1,p2,p3]).then(function(res){
console.log(res);
},function(res){
console.log(res);
})
all()
的參數(shù)應(yīng)是一個數(shù)組。當(dāng)在這個數(shù)組中所有的promise對象都成功才會觸發(fā)成功遍尺,并把數(shù)組中所有promise返回值的數(shù)組作為成功回調(diào)的返回值截酷,順序與數(shù)組中一致。若有任一個對象失敗狮鸭。則會觸發(fā)該primise對象的失敗合搅,并將第一個觸發(fā)失敗的promise對象的錯誤信息作為它的失敗狀態(tài)。
race()方法
all()
是等所有的異步操作都執(zhí)行完了再執(zhí)行then()
方法歧蕉,那么race()
方法就是相反的灾部,誰先執(zhí)行完成就先執(zhí)行回調(diào)。
參考地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise