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 函数返回承诺,但“何时”仍然不等待的主要内容,如果未能解决你的问题,请参考以下文章