【问题标题】:Why is my `then` event firing before my `when` event is finished?为什么我的 `then` 事件在我的 `when` 事件完成之前触发?
【发布时间】:2016-01-19 05:54:09
【问题描述】:

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

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

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

为什么当我将它们设置为 when > then 格式时会发生这种情况?

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

我是否误解了承诺在 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 不会返回一个 pomise,所以 $.when 没有任何关系。此外,您想将一个函数传递给.done。现在您正在调用partialSlide 并将其返回值(即undefined)传递给.donefoo(bar())foo(bar) 非常不同。
  • jsfiddle.net/arunpjohny/306t2cez/1 - 没必要这么复杂
  • load comments返回$.ajax,希望jQuery ajax实现了Promise。
  • @sabithpocker - 确实如此,是的。
  • 你为什么要$.when($.when(...))?你想在那里完成什么?

标签: javascript jquery promise .when


【解决方案1】:

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

function loadComments(divID,postID) {
    return $.ajax({url: "ajax-comments/?post_id=" + postID, success:      
    function(result){
        $("#" + divID + " .comment.list").html(result);
    }});
}   

正如 cmets 中所指出的,这行代码会立即调用 partialSlide,因为末尾有括号。应该是:

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

【讨论】:

  • .done(partialSlide(divID)) 怎么样? - 无论loadComments 是否返回承诺,partialSlide 都会被调用
  • 这只是问题的一部分。
  • partialSlide 看起来就像它的完成功能,所以它不需要返回承诺或任何东西,因为它只是动画高度。 jquery ajax 调用默认返回一个promise。
  • 如果没有给 a 当我相信 done 被立即调用的承诺。
  • @AtheistP3ace: .done(partialSlide(divID)) 应该是 .done(function(){ partialSlide(divID); })
【解决方案2】:

正如已经解释过的 cmets,代码中存在多个问题,例如

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

所以

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

【讨论】:

    猜你喜欢
    • 2014-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 2017-08-29
    • 2014-06-30
    • 1970-01-01
    相关资源
    最近更新 更多