带有嵌套AJAX调用的JavaScript承诺不起作用
在我的代码中,我有一个带有3个嵌套AJAX调用的函数,为了让它工作,我必须将Async=false设置为 正如我所读到的,Async=false已被弃用,我用promissions替换了Async=false 这是我编辑之前的函数:带有嵌套AJAX调用的JavaScript承诺不起作用,javascript,ajax,asynchronous,promise,Javascript,Ajax,Asynchronous,Promise,在我的代码中,我有一个带有3个嵌套AJAX调用的函数,为了让它工作,我必须将Async=false设置为 正如我所读到的,Async=false已被弃用,我用promissions替换了Async=false 这是我编辑之前的函数: self.getOrders = function (name) { var orders= []; var order= function (item, type1, type2) { var self = this;
self.getOrders = function (name) {
var orders= [];
var order= function (item, type1, type2) {
var self = this;
self.order= item;
self.type1= type1;
self.type2= type2;
}
$.ajax({
url: "/API/orders/" + name,
type: "GET",
async: false,
success: function (orderResults) {
var mappedOrders = $.map(orderResults, function (orderItem) {
$.ajax({
url: "/API/orders/property/" + orderItem.id + "/type1",
type: "GET",
async: false,
success: function (property1Results) {
$.ajax({
url: "/API/orders/property/" + orderItem.id + "/type2",
type: "GET",
async: false,
success: function (property2Results) {
orders.push(new order(orderItem, property1Results, property2Results));
}
});
}
});
})
}
});
return orders;
这个函数工作得很好,我得到了数据端,一切都很好
然后我将函数改为使用承诺,而不是Async=false,
这是经过编辑的功能,承诺:
以及函数调用:
self.populateOrders = function (name) {
var mappedOrders = $.map(self.service.getOrders(name), function (item) {
return new Order(item)
});
self.orders(mappedOrders);
}
新函数不起作用,我从firstPromise返回一个带有反斜杠的错误json,返回的orders对象为空
知道我做错了什么吗?我花了那么多时间在这上面,但还是弄不明白
提前谢谢 chrome 2016年8月52日最近引入的一个bug可能会导致这种行为:嵌套请求的答案被忽略。 希望它不会持续太久
尝试添加缓存:false在循环中嵌套ajax调用是一个很难管理的问题。你可以这样做 创建一个承诺,在整个过程完成时通知调用方 等待所有内部ajax调用的解析 解决你的主要承诺,通知来电者
在本例中,请注意,我使用$.when.apply等待延迟数组。请共享函数的其余部分,必要时删除不相关的代码。您需要返回承诺而不是orders数组,并在该承诺的resolve回调中访问您的orders数组。我编辑了我的问题。在嵌套承诺中,您必须返回嵌套承诺。返回secondPromise和thirdPromise,而不是仅声明它们。此外,您必须使用then而不是done来链接承诺。您真的需要嵌套它们吗?看起来它们可以并行运行。虽然这应该可以工作,但请注意,我无法在JSFIDLE中测试这一点,因为您没有提供JSFIDLE。如果您对它有问题,请将它们封装在JSFIDLE中,我将考虑如何解决它。@Bergi的评论使我意识到您的ajax内部ajax调用不需要嵌套。这在一定程度上简化了代码,因此我进行了相应的编辑。非常感谢您的明确回答,我现在将尝试它,并会让您知道,谢谢!这几乎是一个好答案,但你应该避免!如果您只是使用Than进行链接,则无需通知任何内容。避免“完成”和“成功”回调@Ozan它正在工作,但不是完全工作,我正在获取数据,没有任何控制台错误,但是从ajax1和ajax2返回的数据很奇怪,使用ko.toJSON它看起来像:[[{地址:test,城市:test,state:NY,zip:null}],success,{readyState:4,responseText:[\r\n{\r\n\address\:\test\,\r\n\city\:\test\,\r\n\state\:\NY\,\r\n\zip\:null\r\n}\r\n}\r\n],responseJSON}]等。在页面上它看起来是这样的:[对象对象]s,u,c,c,e,s,s4,函数a{var b;if2==t{if!j{j=etc!!
self.populateOrders = function (name) {
var mappedOrders = $.map(self.service.getOrders(name), function (item) {
return new Order(item)
});
self.orders(mappedOrders);
}
self.getOrders = function (name) {
var mainDeferred = $.Deferred();
var orders = [];
var order = function (item, type1, type2) {
var self = this;
self.order = item;
self.type1 = type1;
self.type2 = type2;
}
$.ajax({
url: "/API/orders/" + name,
type: "GET",
success: function (orderResults) {
var innerwait = [];
var mappedOrders = $.map(orderResults, function (orderItem) {
var ajax1 = $.ajax({
url: "/API/orders/property/" + orderItem.id + "/type1",
type: "GET"
});
var ajax2 = $.ajax({
url: "/API/orders/property/" + orderItem.id + "/type2",
type: "GET"
});
$.when(ajax1, ajax2).done(function (property1Results, property2Results) {
orders.push(new order(orderItem, property1Results[0], property2Results[0])))
});
innerwait.push(ajax1, ajax2);
});;
$.when.apply(null, innerwait) //make sure to wait for all ajax requests to finish
.done(function () {
mainDeferred.resolve(orders); //now that we are sure the orders array is filled, we can resolve mainDeferred with orders array
});
}
});
return mainDeferred.promise();
}
self.populateOrders = function (name) {
self.service.getOrders(name).done(function (orders) { //use .done() method to wait for the .getOrders() to resolve
var mappedOrders = $.map(orders, function (item) {
return new Order(item)
});
self.orders(mappedOrders);
});
}