为什么我的'then`事件在我的'when`事件结束之前被触发了?

时间:2015-10-20 14:05:40

标签: javascript jquery promise .when

我的页面上有预览帖子列表。当他们点击时,他们应该加载帖子的全文,加载评论,然后向下滑动以显示两者。

我有一个模拟slideDown的函数partialSlide,但是从指定的高度开始 - 它改编自this answer。另外两个函数,loadFullPost和loadComments都是我的。

所有事件都在触发,但是partialSlide在loadComments完成之前触发,因此在计算高度时它没有考虑它们,因此它们被切断了。

为什么当我在>中设置它们时会发生这种情况?然后格式化?

$.when(loadComments(divID,postID)).done(partialSlide(divID));

我是否误解了jQuery中的promises如何工作?在我的代码中,他们已按预期工作(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);    
}

2 个答案:

答案 0 :(得分:4)

我认为您的问题可能是loadComments没有返回,因此永远不会给予承诺。

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) });

答案 1 :(得分:2)

正如已经解释的那样,评论中存在多个问题,如

  1. $.ajax()返回一个promise对象,因此无需将其传递给$.when()
  2. 由于您需要在loadComments中的ajax请求完成后执行某些操作,因此您需要从中返回一个承诺。由于$.ajax返回一个承诺,您可以返回该值
  3. 您需要将函数引用传递给done(),当您执行partialSlide(divID)时,您实际上是通过传递参数调用函数partialSlide并传递从它返回的值({ {1}}在这种情况下)作为完成回调。
  4. 所以

    undefined