我对这类问题的第一百万次迭代道歉。我已经看过很多其他帖子都在讨论这个问题了,在回调成功并返回之后,我仍无法绕过能够调用函数的问题。我必须读过这篇文章超过六次:
How do I return the response from an asynchronous call?
无论如何..,我的问题,我希望任何人都能说清楚。我有一个自定义的jQuery验证器方法,用于检查用户名是否可用。
jQuery.validator.addMethod("usernameAvailability",
function(value, element) {
console.log('starting usernameAvailability');
if(this.optional(element) === true){return true;}
else{
console.log('ending usernameAvailability, about to return get_availability');
return availabilityCheck.get_availability('username');
}
}, "Username already in use." );
自定义jQuery验证器方法在命名空间availabilityCheck中调用get_availability(element)。
var availabilityCheck = (function() {
var usernameIsAvailable, emailIsAvailable, Callback, AJAX_Availability_Check, change_Availability;
usernameIsAvailable = null;
emailIsAvailable = null;
AJAX_Availability_Check = function(callback, element){
console.log('starting AJAX_Availability_Check');
if(element==="username"){
selection = {username:$('#id_username').val()};
}
else{
selection = {email:$('#id_email').val()};
}
$.ajax({
url: '/register/',
type: 'get',
data: selection,
dataType:'text',
async: true
}).done(Callback(element));
};
change_Availability = function(element, bool) {
if(element === 'username'){
usernameIsAvailable = bool;
}
else{
emailIsAvailable = bool;
}
};
Callback = function(element) {
return function(result, textStatus){
bool = result === "True" ? true: false;
change_Availability(element, bool);
return usernameIsAvailable;
};
};
return{
get_availability: function(element){
AJAX_Availability_Check(Callback, element);
return element === 'username' ? usernameIsAvailable : emailIsAvailable;
}
}
})();
我的问题输入正确验证用户名是否已被使用,但是用户需要触发验证两次,因为get_availability在Callback可以将usernameIsAvailable更改为正确的布尔值之前返回。
我的问题如何重构我的代码,以便回调调用我的自定义jQuery验证方法?或者我如何确保在Callback返回之前它不会被验证?
答案 0 :(得分:1)
问题在于你的结构......我不知道你从哪里得到它但扔掉它然后烧掉它,然后忘了你曾经看过它。
您可以将代码简化为:
var availabilityCheck = function() {
var usernameIsAvailable = null, emailIsAvailable = null,
AJAXAvailabilityCheck, changeAvailability;
AJAXAvailabilityCheck = function(element){
console.log('starting AJAX_Availability_Check');
if(element==="username"){
selection = {username:$('#id_username').val()};
}
else{
selection = {email:$('#id_email').val()};
}
$.ajax({
url: '/register/',
type: 'get',
data: selection,
dataType:'text',
async: true
}).done(changeAvailability(element));
};
changeAvailability = function(element, theBool) {
if(element === 'username'){
usernameIsAvailable = theBool;
}
else{
emailIsAvailable = theBool;
}
};
this.getAvailability = function(element) {
AJAXAvailabilityCheck(element);
return element === 'username' ? usernameIsAvailable : emailIsAvailable;
}
};
所以你的回调现在实际上是有用的,而不仅仅是另一个无用的层
但是正如我在下面指出的那样,你的结果实际上并没有被我所知,所以你必须弄明白theBool
应该是什么。
有些注意事项:
Callback = function(element) {
return function(result, textStatus){
bool = result === "True" ? true: false;
change_Availability(element, bool);
return usernameIsAvailable;
};
};
您没有特殊原因返回匿名函数,并且您的result
变量未定义...至少使用您拥有的代码,因此您拥有它始终解析为{{1 }}。此外,如果您只是检查真实性,那么您不需要元组,您可以false
进行评估为真或假,不需要额外的result === "True"
。
此外,不要将? true : false
之类的单词用于变量名称。 bool
是一种变量,是一个保留字。 Javascript让你使用它导致... Javascript将让你做任何事情,但它的坏习惯。
最后你混合了10种不同类型的套管。现在外壳是个人偏好(我个人更喜欢下划线来camelCase,这是javascript约定),但无论你使用什么情况。 仅使用一个案例
现在我相信你真正的问题是你不明白自我调用函数是什么。
您使用以下语法:Bool
创建自动调用函数;这意味着它会在没有被召唤的情况下发射!这意味着当你的用户还没有输入任何数据时,所有这一切都会调用你的ajax并导致一个无关的服务器命中。
我相信你这样做了所以你可以在你的调用函数中使用这个语法var availabilityCheck = (function(){})();
,但更好的方法是做我上面做的并使availabilityCheck.getAvailability()
属性为{ {1}}使用getAvailability
关键字。然后,您可以使用相同的语法,而无需运行整个函数两次。
你几乎从不(当然总有例外)在自调用函数中放置一个ajax调用。如果调用不依赖于用户输入,那么您应该在第一次请求页面时加载数据。