在学习之前,先看一下以往的请求:
试想:
假如,我在写一个电商网站,然后呢,
当我请求到了顶部导航的数据之后,再请求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以上版本, . a j a x ( ) , 本 身 就 是 用 的 P r o m i s e 写 的 , 所 以 .ajax(),本身就是用的Promise写的,所以 .ajax(),本身就是用的Promise写的,所以.ajax本身就是一个Promise对象,我们也可以用$.ajax来调用.all .then方法。这里就不演示了。
感谢阅读 ,让我们共同进步。
如果有错,或者你认为哪里有错,请评论留言,以便于更好的完善这篇文章,方便大家阅读。