javascript - 调用一个 JS 模块中的方法并向另一个 JS 模块返回数据

标签 javascript

尝试掌握 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。经过更多尝试后,我注意到 authenticatedundefined,这导致我在范围内移动 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,因为该函数始终会在调用 donefail 回调之前返回。

你的整个函数基本上都是这样做的:

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/

相关文章:

javascript - 如何获取表单输入值以替换提交时使用 Angular.js 的表单

javascript - 更新集合中深层嵌套的对象

javascript - 将属性 javascript 合并到新对象中

javascript - 主干模板中的 DOM 元素不响应事件

javascript - 获取可细化字符串的内部 id

javascript - Breeze 合并策略 : overwrite properties, 保留更改

javascript - 无法将 javascript 中的 json api 正确打印到 html

javascript - JQuery:为什么是空的?

javascript - 如何从选择了类的元素发送数据

php - Ajax 返回 false 到表单