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

试图解决javascript中异步代码引起的问题,javascript,firebase-realtime-database,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(sna

我是数据库系统的新手,我尝试做的是检查用户在登录时输入的电子邮件是否存在于数据库中。我使用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(“有这样一个用户”)}
,但我遇到并想要解决的问题不是,这是登录函数中的“回调”函数。当我在外部函数中控制列表时,它会显示一个空列表,因为在外部函数完成之前,它不会运行内部函数。我明白这一点。但我怎样才能避免或解决这个问题呢。我想得到完整的电子邮件列表,以便能够循环浏览。另外,我不知道如何结束Firebase中的“循环”,因为它在收到电子邮件时有点循环。因此,我想在它找到匹配的电子邮件时停止。您正在下载所有用户,以查看是否已经存在一个名称。这是对带宽的浪费

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

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

通常,如果需要处理所有节点,则需要使用一个
事件,该事件一次对所有匹配的节点执行。因此,要从数据库中获取所有用户,请将他们添加到列表中,然后对该列表执行以下操作:

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
})

请注意,您将无法访问回调之外的
列表。即使在回调外部声明变量,也只能在回调内部正确填充该变量。请参阅Xufox的评论,以获得解释原因的链接。

在您拥有它们的地方循环浏览它们。。。在Callback的可能重复的Yes中,我也尝试过,但问题是,一旦找到匹配的电子邮件,我就需要停止拍摄电子邮件快照,因为我收到的警报(无论用户是否存在)与数据库中的电子邮件数量一样多@Jaromandaxa你是说你需要“取消”(因为缺少更好的术语)处理程序上的
“child\u added”
吗?是的,有点。尽管我怀疑这是可能的。@JaromandaX