题目
前端小同砚在做页面的时刻,犯了个罕见的毛病:把多个Ajax请求递次着写下来了,然后面的请求,对前面请求的返回效果,是有依靠的。以下面的代码所示:
var someData;
$.ajax({
url: '/prefix/entity1/action1',
type: 'GET' ,
async: true,
contentType: "application/json",
success: function (resp) {
//do something on response
someData.attr1 = resp.attr1;
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
//在这个页面里,一切的请求的毛病都做一样的处置惩罚
if (XMLHttpRequest.status == "401") {
window.location.href = '/login.html';
} else {
alert(XMLHttpRequest.responseText);
}
}
});
$.ajax({
url: '/prefix/entity2/action2',
type: 'POST' ,
dataType: "json",
data: JSON.stringify(someData),
async: true,
contentType: "application/json",
success: function (resp) {
//do something on response
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
//在这个页面里,一切的请求的毛病都做一样的处置惩罚
if (XMLHttpRequest.status == "401") {
window.location.href = '/login.html';
} else {
alert(XMLHttpRequest.responseText);
}
}
});
以上代码有两个题目:
*起首就是实行递次不能保证,action2很可能在action1返回之前就发出了,致使someData.attr1这个参数没能准确传出
*其次两个ajax请求的代码反复很严重
思绪
代码反复的题目相对好处理,尤其是在本身的项目里,种种参数能够经由过程范例定死,封装一个参数更少的ajax要领就好了
//url:地点
//data:数据对象,在函数内部会转化成json串,假如没传,示意用GET要领,假如传了,示意用POST要领
function ajax(url, data, callback) {
$.ajax({
url: url,
type: data == null ? 'GET' : 'POST',
dataType: "json",
data: data == null ? '' : JSON.stringify(data),
async: true,
contentType: "application/json",
success: function (resp) {
callback(resp);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
if (XMLHttpRequest.status == "401") {
window.parent.location = '/enterprise/enterprise_login.html';
self.location = '/enterprise/enterprise_login.html';
} else {
alert(XMLHttpRequest.responseText);
}
}
});
}
如许只要url,data和callback三个必要的参数要填,其他都定死了
实行递次的题目,能够把第二个请求放在第一个请求的回调里,形如:
ajax('/prefix/entity1/action1',null, function(resp){
//do something on response
someData.attr1 = resp.attr1;
ajax('/prefix/entity2/action2', someData, function(resp){
//do something on response
}
};
至此题目好像处理得很圆满,但能够想见,假如请求不止两个,而是4、5个,同时另有其他异步操纵(比方我们的页面里有Vue对象的初始化),相互之间有依靠关联,光是如许层层叠叠的括号嵌套,就已让人头晕了。
须要找到一种要领,让异步挪用的表达看起来像同步挪用一样。
恰好近来看了阮一峰先生关于ES6的书,而且用户也没有倔强请求兼容IE浏览器,于是就挑选了Promise的计划
处理计划
引入Promise
实在当代浏览器都已内置支撑了Promise,连第三方库都不须要了,只要IE不可,摒弃了革新ajax封装函数,在胜利的时刻挪用resolve(),失利的时刻挪用reject(),而且返回Promise对象
function ajax(url, data, callback) {
var p = new Promise(function (resolve, reject) {
$.ajax({
url: url,
type: data == null ? 'GET' : 'POST',
dataType: "json",
data: data == null ? '' : JSON.stringify(data),
async: true,
contentType: "application/json",
success: function (resp) {
callback(resp);
resolve();
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
if (XMLHttpRequest.status == "401") {
window.parent.location = '/enterprise/enterprise_login.html';
self.location = '/enterprise/enterprise_login.html';
} else {
alert(XMLHttpRequest.responseText);
}
reject();
}
});
});
return p;
}
修正挪用端
ajax('/prefix/entity1/action1',null, function(resp){
//do something on response
someData.attr1 = resp.attr1;
}).then(
ajax('/prefix/entity2/action2', someData, function(resp){
//do something on response
}
).then(
initVue() ;
).then(
//do something else
)
至此圆满处理。
经@miroki 提示,发明Jquery从1.5版最先,返回的就是thenable对象了,那末ajax函数能够直接返回$.ajax()的返回值