将值从Firebase JS回调方法(DAL)返回到另一个函数(控制器)

时间:2016-04-11 21:41:19

标签: javascript jquery asynchronous model-view-controller firebase

我一直致力于一个简单的聊天应用程序,它允许用户在简单的群聊中输入消息,并让他们实时更新/显示。因此我决定使用Firebase,并花了一些时间习惯其Web API。但是,当我尝试手动创建一个简单的用户身份验证系统时,或者只是将值列表返回给另一个函数时,我遇到了一些问题。

我正在尝试遵循MVC模式,HTML表单触发global.js内的事件处理程序,然后调用控制器文件中的相应方法,然后调用DAL中的相应方法。 DAL会转到远程Firebase并执行请求的操作。

我的问题是,在once事件处理程序触发后,我没有得到任何结果。控制器将执行checkUserLogin()方法,但不会将任何内容分配给变量loginValid。据我所知,从调试开始,执行到达事件处理程序的末尾,然后自行删除。我已经阅读了有关异步JS的内容,但并不是真的了解它。

我想要发生的一切是从Firebase检索列表,在将结果从DAL传递给控制器​​之前处理它以进行身份​​验证,然后在控制器中执行结果。出于这些目的,我不关心实时更新,我有时只想返回Firebase列表中数据的当前快照,并在另一个函数内对其执行操作。

这是我的文件结构(必要时)。 global.js包含事件处理程序,负责处理HTML页面事件并选择适当的控制器操作(security_controller.js),然后调用必要的DAL操作(security_dal.js)。

global.js

$(document).ready(function() {
    $("#btnSubmitLogin").on("click", btnSubmitLogin_click);
});

function btnSubmitLogin_click() {
     doUserLogin();
}

security_controller.js

function doUserLogin() {
    var username = $("#txtLoginUsername").val();
    var password = $("#txtLoginPassword").val();

    //Determine if user is logged in, and react accordingly
    var loginValid = checkUserLogin(username, password);

    if (loginValid) {
        navigateToPage("pageHome");
        $("#successMessageLogin").text("Success validating user");
    }
    else {
        navigateToPage("pageLogin");
        $("#errorMessageLogin").text("Error validating user");
    }
}

security_dal.js

function checkUserLogin(username, password) {
    var foundUser = null;
    var loginValid = false;

    fb_ref.once("value", function(snapshot) {
        var list = snapshot.val();

        for (var i in list) {
            if (list[i].username === username && list[i].password === password) {
                foundUser = list[i];
                break;
            }
        }           

        return loginValid;
    });

    if (foundUser !== null) {
        console.info(foundUser.username);
        console.info(foundUser.password);
        loginValid = true;
    }

    return loginValid;
}

我检查了几个类似的搜索,但没有提出任何回答我的问题。在下面的问题/答案中,答案提到了有关异步javascript的问题,并且似乎只是在检索回调函数中的值之后放置需要执行的代码来解决问题。然而,这与我试图用我的“MVC模式”实现的目标背道而驰。 DAL不应该触摸视图,而是将返回的值传递回控制器。

Firebase Query Inside Function Returns Null

理想情况下,这就是我想要发生的事情:

  • global.js来电btnSubmitLogin_click()
  • btnSubmitLogin_click()在控制器中调用doUserLogin
  • 控制器中的
  • doUserLogin在DAL中调用checkUserLogin
  • DAL中的
  • checkUserLogin从Firebase检索用户列表,并查找与输入的凭据匹配的用户
  • DAL中的
  • checkUserLogin向控制器返回true / false并将其分配给变量loginValid
  • 控制器决定如何处理此信息,并根据需要更新视图

注意:我完全清楚Firebase有自己的身份验证,但我想创建自己的简单版本,仅仅是为了体验。因此,我只需要在控制器中操作数据的列表/数组。我也知道过滤/排序的可能性,但我希望使用此方法检查用户,因为我想知道如何检索列表。

如果我完全以错误的方式执行此操作(Firebase新手),或者是否应提供其他内容,请告知我们。谢谢!

1 个答案:

答案 0 :(得分:1)

是的,同步性是关键所在。通常,您可以通过自己的回调来解决这个问题。这样你仍然可以在正确的位置做逻辑。

在这种情况下,您可以为checkUserLogin创建第3个参数:

checkUserLogin(username, password, function(foundUser) {

     if (foundUser) {
         navigateToPage("pageHome");
         $("#successMessageLogin").text("Success validating user");
     } else {
        navigateToPage("pageLogin");
        $("#errorMessageLogin").text("Error validating user");
     }
});

然后:

function checkUserLogin(username, password, callback) {
    fb_ref.once("value", function(snapshot) {
        var list = snapshot.val();
        var foundUser;

        for (var i in list) {
            if (list[i].username === username && list[i].password === password) {
                foundUser = list[i];
                break;
            }
        }           
        callback(foundUser)
    });
}

(倾向于指出未加密的密码等)