Jquery 使用promise的嵌套ajax调用
我需要使用Promise重构标准ajax金字塔。最初,我使用标准的AJAX调用Jquery 使用promise的嵌套ajax调用,jquery,ajax,kendo-ui,promise,kendo-asp.net-mvc,Jquery,Ajax,Kendo Ui,Promise,Kendo Asp.net Mvc,我需要使用Promise重构标准ajax金字塔。最初,我使用标准的AJAX调用async:false。这使得页面速度变慢。因此,我决定用AJAX承诺取代嵌套的AJAX调用 这是我最初的ajax调用 $.ajax({ type:"POST", url:'@Url.Action("GetDesks", "OrderForm")', data:{ String(agents.val())}, async:f
async:false
。这使得页面速度变慢。因此,我决定用AJAX承诺取代嵌套的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?
});
我把承诺应用于第一个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承诺。我只在as3中使用过 但是,如果您想让它们执行异步,请保持getDesk不变。将GetUsers放在第一个.done内成功处理程序的外部,并在下一行执行它,与前面类似 例如 GetUsers.done(func…)
GetDesks.done(func…) 首先,不要使用
async:false
。我也不知道数据:{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
});
组合处理程序是使用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);
});
除了使用承诺之外,主要的变化是将$(“#DeskList”).data(“kendoDropDownList”)…
移动到第二个“成功处理程序”中
这将保证两个列表都被更新,或者两个列表都没有更新,并且在两个列表都被更新后提供了触发(‘更改’)的机会,这可能很重要。在这方面,承诺实际上是不必要的-您可以在原始代码中执行相同的操作(即使使用async:true)。在这种情况下,我如何将成功值从successFunction1传递到下一个AJAX post?我使用async:false在下一个AJAX调用之前延迟kendoDropdownlist筛选。抱歉延迟。我尝试了您的代码,但出现了类似
$.map(…).get的错误。get不是函数
。用谷歌搜索这个问题,发现.map()和$.map()是两个不同的东西。请原谅,$.map()
返回一个数组。我想到的是jQueryCollection.map()
,它返回一个封装在另一个jQuery对象中的数组。答案已编辑。谢谢@Roamer-1888,只需稍作修改,您的代码运行良好。