为什么我的 `then` 事件在我的 `when` 事件完成之前触发?
Why is my `then` event firing before my `when` event is finished?
我的页面上有一个 post 预览列表。单击它们时,它们应该加载 post 的全文,加载评论,然后向下滑动以显示两者。
我有一个函数 partialSlide,它模拟 slideDown,但从指定的高度开始 - 它改编自 this answer。另外两个函数,loadFullPost 和 loadComments 是我的。
所有事件都在触发,但 partialSlide 在 loadComments 完成之前触发,因此在计算高度时没有考虑它们,因此它们被截断了。
当我将它们设置为 when > then 格式时,为什么会发生这种情况?
$.when(loadComments(divID,postID)).done(partialSlide(divID));
我是否误解了 promise 在 jQuery 中的工作方式?在我的代码的其他地方,它们按预期工作(then
仅在 when
完成后运行)。
以下完整功能:
function loadFullPost(permalink,divID,postID) {
$.when($.when($.ajax({url: permalink+"?ajax=true", success:
function(result){$("#"+divID+"").html(result);}})).then
(function( data, textStatus, jqXHR ) {
$.when(loadComments(divID,postID)).done(partialSlide(divID));
}));
}
function loadComments(divID,postID) {
$.ajax({url: "ajax-comments/?post_id=" + postID, success:
function(result){
$("#" + divID + " .comment.list").html(result);
}});
}
function partialSlide(divID) {
var contentHeight = $("#"+divID+"").addClass('full').height();
$("#"+divID+"").removeClass('full').animate({
height: (contentHeight == $("#"+divID+"").height() ? 100 : contentHeight)
}, 500);
}
我认为您的问题可能是 loadComments 没有 return,所以承诺永远不会给 when。
function loadComments(divID,postID) {
return $.ajax({url: "ajax-comments/?post_id=" + postID, success:
function(result){
$("#" + divID + " .comment.list").html(result);
}});
}
正如评论中所指出的,这一行会立即调用 partialSlide,因为您在末尾有括号。应该是:
$.when(loadComments(divID,postID)).done(function () { partialSlide(divID) });
正如评论中所解释的那样,代码中存在多个问题,例如
$.ajax()
return 是一个 promise 对象,因此无需将其传递给 $.when()
- 由于您希望在
loadComments
中的 ajax 请求完成后执行某些操作,因此您需要 return 一个承诺。由于 $.ajax
return 是一个承诺,您可以 return 该值
- 您需要将函数引用传递给
done()
,当您执行 partialSlide(divID)
时,您实际上是通过传递参数调用函数 partialSlide
并传递值 return从它(在这种情况下为undefined
)作为完成回调。
所以
function loadFullPost(permalink, divID, postID) {
$.ajax({
url: permalink + "?ajax=true",
success: function (result) {
$("#" + divID + "").html(result);
loadComments(divID, postID).done(function () {
partialSlide(divID)
})
}
})
}
function loadComments(divID, postID) {
return $.ajax({
url: "ajax-comments/?post_id=" + postID,
success: function (result) {
$("#" + divID + " .comment.list").html(result);
}
});
}
function partialSlide(divID) {
var contentHeight = $("#" + divID + "").addClass('full').height();
$("#" + divID + "").removeClass('full').animate({
height: (contentHeight == $("#" + divID + "").height() ? 100 : contentHeight)
}, 500);
}
我的页面上有一个 post 预览列表。单击它们时,它们应该加载 post 的全文,加载评论,然后向下滑动以显示两者。
我有一个函数 partialSlide,它模拟 slideDown,但从指定的高度开始 - 它改编自 this answer。另外两个函数,loadFullPost 和 loadComments 是我的。
所有事件都在触发,但 partialSlide 在 loadComments 完成之前触发,因此在计算高度时没有考虑它们,因此它们被截断了。
当我将它们设置为 when > then 格式时,为什么会发生这种情况?
$.when(loadComments(divID,postID)).done(partialSlide(divID));
我是否误解了 promise 在 jQuery 中的工作方式?在我的代码的其他地方,它们按预期工作(then
仅在 when
完成后运行)。
以下完整功能:
function loadFullPost(permalink,divID,postID) {
$.when($.when($.ajax({url: permalink+"?ajax=true", success:
function(result){$("#"+divID+"").html(result);}})).then
(function( data, textStatus, jqXHR ) {
$.when(loadComments(divID,postID)).done(partialSlide(divID));
}));
}
function loadComments(divID,postID) {
$.ajax({url: "ajax-comments/?post_id=" + postID, success:
function(result){
$("#" + divID + " .comment.list").html(result);
}});
}
function partialSlide(divID) {
var contentHeight = $("#"+divID+"").addClass('full').height();
$("#"+divID+"").removeClass('full').animate({
height: (contentHeight == $("#"+divID+"").height() ? 100 : contentHeight)
}, 500);
}
我认为您的问题可能是 loadComments 没有 return,所以承诺永远不会给 when。
function loadComments(divID,postID) {
return $.ajax({url: "ajax-comments/?post_id=" + postID, success:
function(result){
$("#" + divID + " .comment.list").html(result);
}});
}
正如评论中所指出的,这一行会立即调用 partialSlide,因为您在末尾有括号。应该是:
$.when(loadComments(divID,postID)).done(function () { partialSlide(divID) });
正如评论中所解释的那样,代码中存在多个问题,例如
$.ajax()
return 是一个 promise 对象,因此无需将其传递给$.when()
- 由于您希望在
loadComments
中的 ajax 请求完成后执行某些操作,因此您需要 return 一个承诺。由于$.ajax
return 是一个承诺,您可以 return 该值 - 您需要将函数引用传递给
done()
,当您执行partialSlide(divID)
时,您实际上是通过传递参数调用函数partialSlide
并传递值 return从它(在这种情况下为undefined
)作为完成回调。
所以
function loadFullPost(permalink, divID, postID) {
$.ajax({
url: permalink + "?ajax=true",
success: function (result) {
$("#" + divID + "").html(result);
loadComments(divID, postID).done(function () {
partialSlide(divID)
})
}
})
}
function loadComments(divID, postID) {
return $.ajax({
url: "ajax-comments/?post_id=" + postID,
success: function (result) {
$("#" + divID + " .comment.list").html(result);
}
});
}
function partialSlide(divID) {
var contentHeight = $("#" + divID + "").addClass('full').height();
$("#" + divID + "").removeClass('full').animate({
height: (contentHeight == $("#" + divID + "").height() ? 100 : contentHeight)
}, 500);
}