在學習之前,先看一下以往的請求:
試想:
假如,我在寫一個電商網站,然後呢,
當我請求到了頂部導航的數據之後,再請求banner圖的數據,
請求完了banner圖數據之後再去請求側邊欄的數據,
那麼問題來了,我們所寫的代碼格式一定是這樣的:
$.ajax({
url:'頂部導航.url'
$.ajax({
url:'banner圖.url'
$.ajax({
url:'側邊欄.url'
})
})
})
這個人一種什麼樣的感覺?是不是感覺看起來很繁瑣,很亂~~
那麼我們就想讓代碼變得像這種:
var 頂部導航 = $.ajax({url:'頂部導航.url'})
var banner圖 = $.ajax({url:'banner圖.url'})
var 側邊欄 = $.ajax({url:'側邊欄.url'})
當然,我們寫的代碼是不可能變成這種格式,這只是我們的理想模式;我們知道,如果這樣寫的話,變量會保存不下來的;因爲這根本就是同步化的寫法,而我們請求的數據卻是異步的。
那麼!
有沒有一種方法可以讓寫法像同步,而本質是異步化呢?
Promise 就出來了。
//XXX.js文件
function promiseAjax(url){
let p = new Promise((resolve,reject)=>{
//第一個參數成功的回調函數
//第二個參數失敗的回調函數
let xhr = new XMLHttpRequest();
xhr.open('get',url,true);
xhr.send();
xhr.onreadystatechange=function(){
if(this.readyState===4){
if(this.status >= 200 && this.status <300 || this.status === 304){
let res = JSON.parse(this.responseText)
resolve(res);//成功回調函數的傳參;
}else{
reject(this.status)//失敗回調函數的傳參;
}
}
}
})
return p
}
//然後調用
let oData = promiseAjax('../data/1.txt')//oData 就是 Promise 的實例
let oData2 = promiseAjax('../data/2.txt')
//new Promise(function(resolve,reject){})
//promise對象 .then 方法接收兩個函數,第一個函數就是resolve,第二個函數是reject
oData.then(function(res){
console.log(res)//1.txt的內容
},function(error){
console.log(error)
})
oData2.then(function(res){
console.log(res)//2.txt的內容
},function(error){
console.log(error)
})
當然這麼寫就是很麻煩,所以有Promise.all方法:
Promise.all([oData,oData2]).then(function(res){
console.log(res)
},function(err){
console.log(err)
})
//注意:當oData或者oData2任何一個請求失敗時,則走的是reject;也就是error;
當然上面寫的就是一個臨時用的Pro’mise,如果用的次數很多,那我們還是封裝一個比較完善的方法。用起來更爲方便;
//下面的方法,封裝了一個更爲完善的ajax,僅此而已;
function promiseAjax (json){
let url = json.url;
let data = json.data||{};
let method = json.type || 'get';
let str = '';
let p = new Promise(function(resolve,reject){
try{
var xhr = new XMLHttpRequest(); //這裏不能用let,作用域問題,之前我把這寫成了let,報錯找不到xhr。
}catch(e){
var xhr = new ActiveXObject('Microsoft.XMLHTTP');//同上
}
if(method.toLowerCase() === 'get'){
for(let i in data){
str += i+'='+data[i]+'&'
}
xhr.open('get',url+'?'+str+Date.now(),true);
xhr.send();
}else if(method.toLowerCase()==='post'){
xhr.open('post',url,true)
xhr.setRequestHeader('Conent-type',"application/x-www-form-urlencoded");
xhr.send(str.substring(0,str.lastIndexOf('&')));
}
xhr.onreadystatechange=function(){
if(this.readyState===4){
if(this.status>=200&&this.status<300||this.status===304){
let response;
try{
response = JSON.parse(this.responseText);
}catch(e){
response = this.responseText;
console.log(e.message)
}finally{
resolve(response)
}
}else{
let erro = new Error();
erro.status = this.status;
reject(erro)
}
}
};
})
return p;
}
//調用:
promiseAjax({
url:'../data/1.txt',
type:'get'
}).then(function(res){
console.log(res)
},function(err){
console.log(err)
})
用.all方法:
let p1 = promiseAjax({
url:'../data/1.txt'
})
let p2 =promiseAjax({
url:'../data/2.txt'
})
Promise.all([p1,p2]).then(function(res){
console.log(res)
},function(err){
console.log(err)
})
需要知道的是JQ3.0以上版本,.ajax本身就是一個Promise對象,我們也可以用$.ajax來調用.all .then方法。這裏就不演示了。
感謝閱讀 ,讓我們共同進步。
如果有錯,或者你認爲哪裏有錯,請評論留言,以便於更好的完善這篇文章,方便大家閱讀。