我试图制作一系列三层嵌套的AJAX调用;基本结构如下(我省略了失败的电话)。
使用eventCalls进入第二级。最终when.apply.done
仅在每次调用event.eventUsers.href
完成后触发,如预期的那样。但是第三个ajax调用,即检索用户信息的event.eventUser.href
调用内部的调用,在when块中的console.log
之后执行。我确定我不完全理解延迟/承诺概念,任何人都可以解决这个问题吗?谢谢!
$.ajax({
type: 'GET'
url: '/api/events'
}).done(function(events, textStatus, jqXHR) {
var eventCalls = [];
$.each(events.items, function(index, event) {
eventCalls.push(
$.ajax({
type: 'GET',
url: event.eventUsers.href // Assoc objects for EventUser
data: 'type=host' // Only one eventUser is returned
}).done(function(eventUsers, textStatus, jqXHR) {
// Getting the eventUser's user information
$.ajax({
type: 'GET',
url: eventUsers.items[0].user.href
}).done(function(user, textStatus, jqXHR) {
event.host = user;
})
})
)
})
$.when.apply($, eventCalls).done(function() {
console.log(events);
})
})
答案 0 :(得分:1)
使用以下内容简化了整个过程:
$.get()
代替$.ajax()
$.map()
创建承诺数组并更正:
.then()
取代.done()
全部通过$.get('/api/events').then(function(events) {
var queryString = 'type=host';//defined outside the $.map() loop for efficiency.
var promises = $.map(events.items, function(item) {//$.map() loops through events.items and returns an array
return $.get(item.eventUsers.href, queryString).then(function(eventUsers) {//note `return`
return $.get(eventUsers.items[0].user.href).then(function(user) {//note `return`
item.host = user;
return item;//this return determines the value with which the final promise is resolved.
});
});
});
//at this point, `promises` is an array of promises each of which will be resolved when its `item.host` has been set
$.when.apply(null, promises).then(function() {
console.dir(events);
});
});
答案 1 :(得分:0)
正如Bergi所指示的那样,解决方案是在嵌套的AJAX调用中用done
替换then
并将值return
替换为done
。
then
和done
之间的区别在于then
添加了处理程序并返回相同的承诺,而then
添加了处理程序并返回一个新的承诺,当您从eventCalls.push(
$.ajax({
type: 'GET',
url: event.eventUsers.href,
data: 'type=host'
}).then(function(eventUsers) { // `then` chaines promises
return $.ajax({ // Promises chain with return values
type: 'GET',
url: eventUsers.items[0].user.href
}).then(function(user, textStatus, jqXHR) {
event.host = user; // synchronous so no big deal done would work
}).then(function(){ return event; }); // resolve with event to show
})
)
结算的内容时,该承诺会解决。
.map
作为提示 - 您可以使用.each
代替{{1}}。