JQuery 函数返回承诺,但“何时”仍然不等待

Posted

技术标签:

【中文标题】JQuery 函数返回承诺,但“何时”仍然不等待【英文标题】:JQuery function returns promise but 'when' still doesn't wait 【发布时间】:2017-10-17 07:52:31 【问题描述】:

我刚刚了解了$.when().then() 功能。我一直在努力让它发挥作用,我已经看过很多例子,但我显然还没有完全理解,因为我无法让它发挥作用。我知道我作为参数传递给when() 函数的任何函数都必须返回一个promise 对象。我觉得我所做的应该有效,但它并没有那么清楚,我仍然不理解某些东西。在我下面的代码中,loadUserInterfaceGroupsDropDown()initializeUserInterfaceGroups() 内部的 ajax 调用完成之前执行。请注意,我返回了 ajax 调用的结果。这应该会产生与我看到的许多将 ajax 调用作为参数传递给 when() 语句的简单示例相同的结果。我还在底部的 else 语句中返回了一个承诺。但由于这似乎不起作用,我显然误解了一些东西。请帮忙。

$.when(initializeUserInterfaceGroups()).then(loadUserInterfaceGroupsDropDown());

function initializeUserInterfaceGroups() 
    if (userInterfaceGroups === undefined) 
        // get the UserInterfaceGroups
        return $.ajax(
            type: "POST",
            url: "Users.aspx/GetUserInterfaceGroups",
            data: "organizationId: " + $("#ddOrganization").val() + "",
            datatype: "json",
            contentType: "application/json; charset=utf-8",
            success: function(response) 
                if (response.d.Success) 
                   userInterfaceGroups = response.d.UserInterfaceGroups;
                   //loadUserInterfaceGroupsDropDown();
                    renderCheckboxLists();
                 else 
                   alert(response.d.ErrorMessage);
                
            ,
            failure: function(response) 
               alert('Error getting the UserInterfaceGroups: ' + response.d);
            
        );
     else 
        return $.Deferred().promise();
    

【问题讨论】:

$.Deferred().promise(); 返回一个永远不会解决的承诺。我不认为那是你想要的。 【参考方案1】:

.when().then() 与多个ajax 函数一起使用的正确语法如下:

$.when($.ajax(...), $.ajax(...)).then(function (resp1, resp2) 
    //this callback will be fired once all ajax calls have finished.
);

所以基本上你需要像上面那样改变你的调用方法。希望对您有所帮助!

【讨论】:

是的,做到了!谢谢。 +1。顺便说一句,只是吹毛求疵,但不应该是$.when($.ajax(...), $.ajax(...)).then(function (resp1) ...).catch(resp2) ...) 吗?只是为了可链性。我知道所需的语义值得商榷。 谢谢!我相信.catch() 可以用来捕捉错误? 正确,我想我现在很困惑。 resp2代表什么? @MaheshSinghChouhan 感谢您的解释!你是 100% 正确的。我一直忘记 jQuery 的 Promise/deferred API 与许多其他 API 有何不同。【参考方案2】:

这似乎不起作用 - 我显然误解了一些东西。

$.when(initializeUserInterfaceGroups()).then(loadUserInterfaceGroupsDropDown());

是的,有两件事:

当你已经有一个承诺时,你绝对不需要$.when。只有当你不确定调用的返回值是否是一个承诺,或者当你有多个承诺等待时,你才应该使用它。这里也不是。 then 采用回调函数。您不能立即调用loadUserInterfaceGroupsDropDown()(这就是它不等待的原因)并将结果传递给then,您必须传递函数本身。 (或者至少将调用包装在函数表达式中)。

所以你的代码应该是这样的

initializeUserInterfaceGroups().then(loadUserInterfaceGroupsDropDown);

【讨论】:

【参考方案3】:

我想我会更新我所做的。我仍在学习有关如何最好地使用它的新事物。最后,它仍然是我需要的完美答案,但我确实必须改变一些事情。有人指出,我在我的一个 ajax 调用中的 else 语句中返回了一个未解决的承诺。 虽然这似乎暂时对我有用,但这是我需要进一步研究的东西。这是我的工作代码,希望它对某人有所帮助。我这样做是因为即使得到了正确的答案,我仍然需要弄清楚一些事情,所以希望这会对某人有所帮助:

$.when(getUserInterfaceGroups(), getUserDetail($(this).attr("data-userId"))).done(function(resp1, resp2) 
    renderUserInterfaceGroupControls(resp1[0], resp2[0]);
    populateForm(resp2[0]);
);

function getUserInterfaceGroups() 
    if (userInterfaceGroups === undefined) 
        return $.ajax(
            type: "POST",
            url: "Users.aspx/GetUserInterfaceGroups",
            data: "organizationId: " + $("#ddOrganization").val() + "",
            datatype: "json",
            contentType: "application/json; charset=utf-8",
            failure: function(response) 
                alert('Error getting the UserInterfaceGroups: ' + response.d);
            
        );
     else 
        return $.Deferred().promise();
    


function getUserDetail(userId) 
    return $.ajax(
        type: "POST",
        url: "Users.aspx/GetUser",
        data: "userId: " + userId + "",
        datatype: "json",
        contentType: "application/json; charset=utf-8",
        failure: function (response) 
            alert('Error getting the User details: ' + response.d);
        
    );


function renderUserInterfaceGroupControls(resp1, resp2) 
    if (resp1.d.Success && resp2.d.Success) 
        userInterfaceGroups = resp1.d.UserInterfaceGroups;
        loadUserInterfaceGroupsDropDown(resp2.d.UserDetail.InterfaceModeId);
        renderCheckboxLists();
     else 
        alert(response.d.ErrorMessage);
    


function populateForm(response) 
    if (response.d.Success) 
        var userDetails = response.d.UserDetail;
        $("#txtUserCode").val(userDetails.UserCode);
        $("#txtName").val(userDetails.Name);
        $("#txtPassCode").val(userDetails.PassCode);
        $("#ddUserInterfaceGroup option[value='" + userDetails.UserInterfaceGroupId + "']").prop("selected", true);
        $("#txtEmail").val(userDetails.Email);
        $("#dtBirthDate").val(userDetails.DateOfBirth);
        $.each(userDetails.ContactGroupIds, function (idx) 
            $("div input[type=checkbox][value=" + userDetails.ContactGroupIds[idx] + "]").prop('checked', true);
        );
        if (userDetails.AssetTagNumber === "") 
            $("#rbUserOwned").prop("checked", "checked");
         else 
            $("#txtAssetTag").val(userDetails.AssetTagNumber);
        
        $("#hidUserId").val(userDetails.Id);
        showInputFields();
     else 
        alert(response.d.ErrorMessage);
    

【讨论】:

以上是关于JQuery 函数返回承诺,但“何时”仍然不等待的主要内容,如果未能解决你的问题,请参考以下文章

从异步函数返回的承诺中获取价值

承诺等待得到解决而不返回

ES8等待电话不等我

返回 jQuery 承诺的 Vuex 动作不起作用,.fail 不是函数

什么是everyauth 承诺?

Javascript等待Promise在返回响应之前完成for循环