使用 promise 的嵌套 ajax 次调用
Nested ajax calls using promise
我需要使用 Promise 重构一个标准的 ajax 金字塔。最初我使用 async:false
的标准 AJAX 调用。这使得页面变慢了。所以我决定用 AJAX Promise.
替换嵌套的 AJAX 调用
这是我原来的 ajax 电话。
$.ajax({
type:"POST",
url:'@Url.Action("GetDesks", "OrderForm")',
data:{ String(agents.val())},
async:false,
success:function (desks) {
if (desks!=undefined || desks!=null || desks!= '') {
var deskList=$("#DeskList").data("kendoDropDownList");
deskList.dataSource.data(desks);
deskList.value("");
deskList.trigger('change');
var desklist = $.map(desks, function(val,index) {
return val.Value;
}).join(",");
$.ajax({
type:"POST",
url:'@Url.Action("GetUsers", "OrderForm")',
data:{ Desks:desklist },
async:false,
success:function (users) {
if (users!=undefined || users!=null || users!= '') {
var usersList=$("#DeskUsers").data("kendoDropDownList");
usersList.dataSource.data(users);
usersList.select(0);
usersList.refresh();
}
},
});
}
},
});
我尝试将上面的修改为:
$.ajax({
type:"POST",
url:'@Url.Action("GetDesks", "OrderForm")',
data:{ String(agents.val())}
}).done(function (desks) {
if (desks!=undefined || desks!=null || desks!= '') {
var deskList=$("#DeskList").data("kendoDropDownList");
deskList.dataSource.data(desks);
deskList.value("");
deskList.trigger('change');
var desklist = $.map(desks, function(val,index) {
return val.Value;
}).join(",");
$.ajax({
type:"POST",
url:'@Url.Action("GetUsers", "OrderForm")',
data:{ Desks:desklist }
})
//How to apply promise after this?
});
我将 promise 应用于拳头 ajax 调用。但是在将相同的方法应用于第二个 ajax 调用时有点混乱。
我如何应用上述案例的承诺?
我从未使用过 ajax 承诺。我只用过as3.
但是,如果您希望他们异步执行,请让您的 GetDesks 保持不变。在第一个 .done 内的成功处理程序之外获取 GetUsers,并在类似于之前的下一行中执行它。
例如
GetUsers.done(函数...);
GetDesks.done(函数...);
首先,不要使用async: false
。我也不知道 data: {String(agents.val())}
语法是什么,但您可以将代码改进为:
$.post('@Url.Action("GetDesks", "OrderForm")', { Agents: String(agents.val()) }).then(function(desks) {
if (desks != undefined || desks != null || desks != '') {
var deskList = $("#DeskList").data("kendoDropDownList");
deskList.dataSource.data(desks);
deskList.value("");
deskList.trigger('change');
var desklist = $.map(desks, function(val, index) {
return val.Value;
}).join(",");
return $.post('@Url.Action("GetUsers", "OrderForm")', { Desks: desklist }).then(function() {
if (users != undefined || users != null || users != '') {
var usersList = $("#DeskUsers").data("kendoDropDownList");
usersList.dataSource.data(users);
usersList.select(0);
usersList.refresh();
}
});
}
}).then(function() {
// both operatioins are completed
});
组合handler就是使用Promise接口的then()方法
它接受所有三个处理程序作为参数。关于 jQuery,在 1.8 版本之前,
您可以将函数数组传递给 then() 方法:
像这样
$.ajax({url: "/ServerResource.txt"}).then([successFunction1, successFunction2, successFunction3],
[errorFunction1, errorFunction2]);
//same as
var jqxhr = $.ajax({
url: "/ServerResource.txt"
});
jqxhr.done(successFunction1);
jqxhr.done(successFunction2);
jqxhr.done(successFunction3);
jqxhr.fail(errorFunction1);
jqxhr.fail(errorFunction2);
根据一些假设,您似乎想要这样的东西:
$.ajax({
url: '@Url.Action("GetDesks", "OrderForm")',
type: 'POST',
data: { 'Agents': agents.val() } //probably?
}).then(function (desks) {
if (desks) {
return $.ajax({
url: '@Url.Action("GetUsers", "OrderForm")',
type: 'POST',
data:{ 'Desks': $.map(desks, function(val) { return val.Value; }).join() }
}).then(function (users) {
if (users) {
// `desks` is still in scope allowing *both* kendoDropDownLists to be updated together
var usersList = $("#DeskUsers").data("kendoDropDownList");
usersList.dataSource.data(users);
usersList.select(0);
usersList.refresh();
var deskList = $("#DeskList").data("kendoDropDownList");
deskList.dataSource.data(desks);
deskList.value("");
deskList.trigger('change'); //probably do this last?
} else {
return new Error('No users found');
}
}, function(jqXHR, textStatus, errorThrown) {
return new Error(textStatus);
});
} else {
return new Error('No desks found');
}
}, function(jqXHR, textStatus, errorThrown) {
return new Error(textStatus);
}).fail(function(error) {
console.log(error);
});
除了使用 promises 之外,主要的变化是将 $("#DeskList").data("kendoDropDownList")...
移动到第二个 "success handler"。
这将保证两个列表都更新,或都不更新,并提供机会 `.trigger('change') 在两个列表都更新后,这可能很重要。在这方面实际上不需要承诺 - 您可以在原始代码中执行相同的操作(即使使用 async:true)。
我需要使用 Promise 重构一个标准的 ajax 金字塔。最初我使用 async:false
的标准 AJAX 调用。这使得页面变慢了。所以我决定用 AJAX Promise.
这是我原来的 ajax 电话。
$.ajax({
type:"POST",
url:'@Url.Action("GetDesks", "OrderForm")',
data:{ String(agents.val())},
async:false,
success:function (desks) {
if (desks!=undefined || desks!=null || desks!= '') {
var deskList=$("#DeskList").data("kendoDropDownList");
deskList.dataSource.data(desks);
deskList.value("");
deskList.trigger('change');
var desklist = $.map(desks, function(val,index) {
return val.Value;
}).join(",");
$.ajax({
type:"POST",
url:'@Url.Action("GetUsers", "OrderForm")',
data:{ Desks:desklist },
async:false,
success:function (users) {
if (users!=undefined || users!=null || users!= '') {
var usersList=$("#DeskUsers").data("kendoDropDownList");
usersList.dataSource.data(users);
usersList.select(0);
usersList.refresh();
}
},
});
}
},
});
我尝试将上面的修改为:
$.ajax({
type:"POST",
url:'@Url.Action("GetDesks", "OrderForm")',
data:{ String(agents.val())}
}).done(function (desks) {
if (desks!=undefined || desks!=null || desks!= '') {
var deskList=$("#DeskList").data("kendoDropDownList");
deskList.dataSource.data(desks);
deskList.value("");
deskList.trigger('change');
var desklist = $.map(desks, function(val,index) {
return val.Value;
}).join(",");
$.ajax({
type:"POST",
url:'@Url.Action("GetUsers", "OrderForm")',
data:{ Desks:desklist }
})
//How to apply promise after this?
});
我将 promise 应用于拳头 ajax 调用。但是在将相同的方法应用于第二个 ajax 调用时有点混乱。
我如何应用上述案例的承诺?
我从未使用过 ajax 承诺。我只用过as3.
但是,如果您希望他们异步执行,请让您的 GetDesks 保持不变。在第一个 .done 内的成功处理程序之外获取 GetUsers,并在类似于之前的下一行中执行它。
例如
GetUsers.done(函数...);
GetDesks.done(函数...);
首先,不要使用async: false
。我也不知道 data: {String(agents.val())}
语法是什么,但您可以将代码改进为:
$.post('@Url.Action("GetDesks", "OrderForm")', { Agents: String(agents.val()) }).then(function(desks) {
if (desks != undefined || desks != null || desks != '') {
var deskList = $("#DeskList").data("kendoDropDownList");
deskList.dataSource.data(desks);
deskList.value("");
deskList.trigger('change');
var desklist = $.map(desks, function(val, index) {
return val.Value;
}).join(",");
return $.post('@Url.Action("GetUsers", "OrderForm")', { Desks: desklist }).then(function() {
if (users != undefined || users != null || users != '') {
var usersList = $("#DeskUsers").data("kendoDropDownList");
usersList.dataSource.data(users);
usersList.select(0);
usersList.refresh();
}
});
}
}).then(function() {
// both operatioins are completed
});
组合handler就是使用Promise接口的then()方法
它接受所有三个处理程序作为参数。关于 jQuery,在 1.8 版本之前,
您可以将函数数组传递给 then() 方法:
像这样
$.ajax({url: "/ServerResource.txt"}).then([successFunction1, successFunction2, successFunction3],
[errorFunction1, errorFunction2]);
//same as
var jqxhr = $.ajax({
url: "/ServerResource.txt"
});
jqxhr.done(successFunction1);
jqxhr.done(successFunction2);
jqxhr.done(successFunction3);
jqxhr.fail(errorFunction1);
jqxhr.fail(errorFunction2);
根据一些假设,您似乎想要这样的东西:
$.ajax({
url: '@Url.Action("GetDesks", "OrderForm")',
type: 'POST',
data: { 'Agents': agents.val() } //probably?
}).then(function (desks) {
if (desks) {
return $.ajax({
url: '@Url.Action("GetUsers", "OrderForm")',
type: 'POST',
data:{ 'Desks': $.map(desks, function(val) { return val.Value; }).join() }
}).then(function (users) {
if (users) {
// `desks` is still in scope allowing *both* kendoDropDownLists to be updated together
var usersList = $("#DeskUsers").data("kendoDropDownList");
usersList.dataSource.data(users);
usersList.select(0);
usersList.refresh();
var deskList = $("#DeskList").data("kendoDropDownList");
deskList.dataSource.data(desks);
deskList.value("");
deskList.trigger('change'); //probably do this last?
} else {
return new Error('No users found');
}
}, function(jqXHR, textStatus, errorThrown) {
return new Error(textStatus);
});
} else {
return new Error('No desks found');
}
}, function(jqXHR, textStatus, errorThrown) {
return new Error(textStatus);
}).fail(function(error) {
console.log(error);
});
除了使用 promises 之外,主要的变化是将 $("#DeskList").data("kendoDropDownList")...
移动到第二个 "success handler"。
这将保证两个列表都更新,或都不更新,并提供机会 `.trigger('change') 在两个列表都更新后,这可能很重要。在这方面实际上不需要承诺 - 您可以在原始代码中执行相同的操作(即使使用 async:true)。