一誊垢、異步編程
?由于JavaScript是單線程的荸镊,一次只能執(zhí)行一個(gè)任務(wù),如果有多個(gè)任務(wù)阅束,那么就需要排隊(duì)呼胚,但是這樣有一個(gè)缺點(diǎn),當(dāng)JavaScript某部分代碼耗時(shí)過長就會拖慢整個(gè)程序的運(yùn)行息裸,由此蝇更,就產(chǎn)生了JavaScript異步編程沪编,往往應(yīng)用于一些耗時(shí)較長的操作,如涉及到IO的讀寫操作簿寂。其主要代碼分為兩部分漾抬,一部分為啟動任務(wù),另一部分為需求數(shù)據(jù)返回后的回調(diào)函數(shù)常遂,啟動任務(wù)部分執(zhí)行后并不立即執(zhí)行回調(diào)函數(shù)纳令,而是執(zhí)行接下來的操作,待請求的數(shù)據(jù)返回后再調(diào)用回調(diào)函數(shù)處理數(shù)據(jù)克胳,但是平绩,當(dāng)有多層嵌套的回調(diào)函數(shù)時(shí),整個(gè)代碼會變得非衬恚混亂捏雌,同時(shí),多個(gè)連續(xù)的異步操作也難以控制其返回值的返回時(shí)間笆搓,所以就有了Promise對象的出現(xiàn)性湿。
二、什么是Promise
?Promise實(shí)際上是標(biāo)準(zhǔn)化的異步編程接口满败,即肤频,他就是為了解決原有的異步編程問題而出現(xiàn)的。
?Promise對象是異步操作與回調(diào)函數(shù)之間的中介算墨,使程序具備正常的回調(diào)函數(shù)的流程宵荒,而不必再一層一層嵌套。
?Promise對象有三種狀態(tài)净嘀,分別為pending(未完成)报咳、fufilled(完成)、rejected(失敗)挖藏,根據(jù)請求結(jié)果暑刃,狀態(tài)變化可能是由pending至fufilled(成功)或由pending至rejected(失敗)
?Promise實(shí)例:
new Promise(
function(resolve, reject) {...}
);
?Promise實(shí)例由Promise構(gòu)造函數(shù)生成,構(gòu)造函數(shù)接受一個(gè)函數(shù)作為參數(shù)膜眠,其中resolve與reject為參數(shù)函數(shù)的兩個(gè)參數(shù)稍走,這兩個(gè)參數(shù)也是函數(shù),前者調(diào)用表示請求成功柴底,后者調(diào)用表示請求失敗婿脸,調(diào)用時(shí)都可以傳出參數(shù)以供后續(xù)的then調(diào)用,eg:
var pro=new Promise(function(resolve,reject){
resolve("哈哈")
})
pro.then(function(value){
console.log(value); //"哈哈"
})
?關(guān)于then柄驻,then部署在Promise對象的原型上狐树,供Promise實(shí)例調(diào)用,可制定兩個(gè)參數(shù)鸿脓,分別為Promise異步操作成功和失敗時(shí)的回調(diào)函數(shù)抑钟,eg:
promise.then(onFulfilled,onRejected)
?onFulfilled函數(shù)會接收到promise中resolve函數(shù)傳來的參數(shù)涯曲,同理,onRejected函數(shù)會接收到promise中reject函數(shù)傳來的參數(shù)在塔。
?值得一提的時(shí)每個(gè)then方法都會反悔一個(gè)Promise對象幻件,所以可以鏈?zhǔn)秸{(diào)用,類似:
promise.then().then()
?關(guān)于catch蛔溃,事實(shí)上 promise.catch(onRejected)
相當(dāng)于promise.then(undefined,onRejected)
的語法糖,即catch只為失敗時(shí)指定處理函數(shù)绰沥。
三、Promise應(yīng)用
Ajax:
function ajax(obj){
return new Promise(function(resolve,reject){
var method=obj.method||"GET";
var url=obj.url||location.href;
var xhr=new XMLHttpRequest();
xhr.open(method,url);
xhr.onreadystatechange=function () {
if(xhr.readyState===4){
if(xhr.status===200){
resolve.call(undefined,xhr.responseText)
}else{
reject.call(undefined,xhr.status)
}
}
}
xhr.send()
})
}
ajax({method:"GET",url:"./method.js"}).then(function(value){console.log("成功了"+value)},function(reason){console.log("失敗了"+reason)})