尝试掌握 JS 中的模块化编程模式。我在从另一个模块调用一个模块中的方法(根据条件返回 true 或 false)并使用返回的数据时遇到困难。
这是我的第一个模块的精简版本:
var stAuthentication = (function() {
return {
someMethod: function() {
///
},
isAuthenticated: function() {
var authenticated;
ajax_isAuthenticated = $.ajax({
url: root+'/assets/scripts/php/app/isAuthenticated',
type: 'POST',
dataType: 'text'
});
ajax_isAuthenticated.done(function(response) {
authenticated = response;
console.log("Ajax request returned "+authenticated);
});
ajax_isAuthenticated.fail(function(response) {
console.log("Ajax request (ajax_isAuthenticated) failed.");
});
if (authenticated == 0) {
return false;
} else {
return true;
}
},
someOtherMethod: function() {
///
}
}
})();
如您所见,有问题的方法是isAuthenticated()。这基本上会向服务器发送一个 AJAX 请求,在服务器中检查用户是否登录并返回 1 或 0。我已经测试了此响应,它按预期工作。我的问题是下一个模块,我将调用第一个示例中的方法来确定用户在第二个模块中运行任务之前是否已登录。这是:
var stReadLater = (function() {
var elements, quantity;
return {
someMethod: function() {
//
},
saveItem: function() {
if (stAuthentication.isAuthenticated()) {
console.log("Signed in");
// user is signed in so use this feature
} else {
console.log("Not signed in");
// ask user to sign in before using this feature
}
},
someOtherMethod: function() {
//
}
}
})();
我认为问题的实际位置是第一个模块中的这几行:
if (authenticated == 0) {
return false;
} else {
return true;
}
首先,我注意到它总是返回 false。经过更多尝试后,我注意到 authenticated
是 undefined
,这导致我在范围内移动 varauthentiated
但没有运气。我也尝试了 this.authenticated
但没有运气。
我知道我已经相当接近了,但我尝试了很多不同的变化,但我完全迷失了。这样做的正确方法是什么?
========================== 修复
我在 AJAX 设置之前检查了 authenticated
变量。感谢@willma 的建议。如果其他人遇到此问题,我就是这样做的:
isAuthenticated: function() {
var deferred = $.Deferred();
ajax_isAuthenticated = $.ajax({
url: root+'/assets/scripts/php/app/isAuthenticated',
type: 'POST',
dataType: 'text'
});
ajax_isAuthenticated.done(function(response) {
deferred.resolve(response)
});
return deferred.promise();
}
然后在第二个模块中:
saveItem: function() {
$.when(stAuthentication.isAuthenticated()).then(function(response) {
if (response == 0) {
console.log("Not signed in");
} else {
console.log("Is signed in");
}
});
}
最佳答案
您混淆了同步和异步代码。 isAuthenticated
将始终返回 false,因为该函数始终会在调用 done
或 fail
回调之前返回。
你的整个函数基本上都是这样做的:
var authenticated;
if (authenticated == 0) { // This is the case because undefined == 0 -> true
return false;
} else {
return true;
}
您有两种解决方案。 stReadLater 对象可以传递如下回调函数:
function done() {
console.log("Signed in");
}
function fail() {
console.log("Not signed in");
}
stReadLater.saveItem = function() {
stAuthentication.isAuthenticated(done, fail);
}
然后是您的身份验证模块:
var stAuthentication.isAuthenticated = function(done, fail) {
ajax_isAuthenticated = $.ajax({
url: root+'/assets/scripts/php/app/isAuthenticated',
type: 'POST',
dataType: 'text'
});
ajax_isAuthenticated.done(done);
ajax_isAuthenticated.fail(fail);
}
或者你可以使用 promise 。我发现 Promise 更优雅。值得reading about them
关于javascript - 调用一个 JS 模块中的方法并向另一个 JS 模块返回数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24130089/