试图解决javascript中异步代码引起的问题

时间:2018-05-28 02:09:44

标签: javascript firebase-realtime-database

我是数据库系统的新手,我要做的是检查用户在登录期间输入的电子邮件是否存在于数据库中。我使用的是Firebase数据库。所以,我写的代码是:

function login(){
    var e_mail = document.getElementById("e-mail").value;
    rootRef = firebase.database().ref();
    rootRef.orderByChild("E_mail").on("child_added", function(snapshot){
        lst.push(snapshot.val().E_mail);
        //console.log(lst);
    })
    console.log(lst);
}

let lst = [];
login_btn.onclick = function() {login()};

我想从数据库中获取所有电子邮件,将它们添加到列表中,然后遍历该列表。也许这不是最好的方式,但这正是我正在努力的方向。我也可以说if (snapshot.val().E_mail == e_mail){alert("there is such a user");}但是我遇到并想要处理的问题不是那个,它是登录功能中的“回调”功能。当我在外部函数中控制列表时,它显示一个空列表,因为它不会运行内部函数,直到完成外部函数。我理解这一点。但是我怎样才能避免或解决这个问题。我想获得完整的电子邮件列表,然后才能循环播放它。另外,我不知道如何结束Firebase中的“循环”,因为它在获取电子邮件时会有一些循环。所以我想在找到匹配的电子邮件时停下来。

1 个答案:

答案 0 :(得分:1)

您正在下载所有用户以查看是否已存在一个名称。这是浪费带宽。

相反,您应该使用查询来匹配您正在寻找的电子邮件,并且只读取该节点:

rootRef.orderByChild("E_mail").equalTo(e_mail).once("value", function(snapshot){
    if (snapshot.exists()) {
        // A node with the requested email already exists
    }
})

通常,如果您需要处理所有节点,那么您将要使用value事件,该事件会立即对所有匹配的节点执行。因此,要从数据库中获取所有用户,请将它们添加到列表中,然后对该列表执行某些操作:

rootRef.orderByChild("E_mail").once("value", function(snapshot){
    var list = [];
    snapshot.forEach(function(childSnapshot) {
        list.push(childSnapshot.val());
    });
    console.log(list); // this will display the populated array
})

请注意,您无法访问回调之外的list。即使您在回调之外声明变量,它也只会在回调中正确填充 。见Xufox'评论链接,解释原因。