繁体   English   中英

使用从Firebase返回的数据获取Javascript

[英]Using data returned from Firebase fetch Javascript

Web开发新手在这里。 我将Firebase用作后端,并且遇到一种情况,我需要在数据库中查询一个值,然后使用该返回值在另一个查询中与该数据库匹配。

这是我的代码:

function dataLoad() {

    var valueThatINeedToUseElsewhere

    userReference.on('value',function(users){
        var currentUser = firebase.auth().currentUser.uid
        users.forEach(function(user){
            if(user.key === currentUser) {
                valueThatINeedToUseElsewhere = user.val().userName
                console.log(valueThatINeedToUseElsewhere)
            }
        })
    })
    console.log(valueThatINeedToUseElsewhere)
}

IF条件中的console.log记录正确的值。 但是,尽管变量名是在“ on”函数外部声明的,但是上面的最后一个console.log并没有记录任何内容。 为什么会这样呢? 以及如何实际使用“ on”功能之外的数据? 我需要使用它在另一个数据检索操作中执行类似的IF条件。

谢谢!

您可能现在正在尝试执行以下操作:

var valueThatINeedToUseElsewhere;
dataLoad();
doSomethingWith(valueThatINeedToUseElsewhere);

不幸的是,这是行不通的,因为(如Doug所说)数据是从Firebase异步加载的。 在您尝试使用valueThatINeedToUseElsewhere ,尚未加载该值。

为什么这行不通,一三十二测试

如果您放置一些这样的日志语句,最容易看到这一点:

console.log("Before starting to load value")
userReference.on('value',function(users){
    console.log("Loaded value")
})
console.log("After starting to load value")

当您运行此代码时,它将打印:

开始加载值之前

开始加载后的值

加载值

那可能不是您期望的顺序。 但这完美地解释了为什么尝试时无法使用 valueThatINeedToUseElsewhere原因:尚未加载它。

解决问题

我发现处理这种情况的最佳方法是重新构造问题。 您当前的代码是按照“首先加载值,然后对值进行处理”的逻辑编写的。 对于异步加载,最好将其构造为“首先开始加载数据。一旦开始加载数据,请对其进行处理”。

在如下代码中:

function dataLoad() {
    userReference.once('value',function(users){
        var currentUser = firebase.auth().currentUser.uid
        users.forEach(function(user){
            if(user.key === currentUser) {
                var valueThatINeedToUseElsewhere = user.val().userName
                doSomethingWith(valueThatINeedToUseElsewhere)
            }
        })
    })
}

正如你所看到的,我们移动的数据需要时数据是可用的触发回调的代码。 这样,您可以确保在调用doSomethingWith时数据可用。 我还更改了代码以使用once ,这(如道格所说)更适合您的用例。

还需要执行两个步骤,以提高代码的灵活性和性能。

传递一旦加载数据即调用的函数

首先,在最后一次更新中,对doSomethingWith的调用是硬编码的,这意味着dataLoad()doSomethingWith是紧密联系在一起的。 通常最好将它们分开。 为此,我们可以将所谓的回调函数传递到dataLoad中,然后在加载数据后调用它。 这与once()已经完成的工作非常相似。 让我们在实践中看一下:

function dataLoad(callback) {
    userReference.once('value',function(users){
        var currentUser = firebase.auth().currentUser.uid
        users.forEach(function(user){
            if(user.key === currentUser) {
                var valueThatINeedToUseElsewhere = user.val().userName
                callback(valueThatINeedToUseElsewhere)
            }
        })
    })
}

没什么不同。 但是现在您可以像这样调用dataLoad

dataLoad(doSomethingWith);

并且,一旦数据被加载, doSomethingWith将与数据一起调用。

按其键加载数据

最后的更改是优化。 您当前的代码正在加载所有用户,而您只需要一个并知道他们的密钥。 仅加载该特定用户的效率更高:

function dataLoad(callback) {
    var currentUser = firebase.auth().currentUser.uid
    userReference.child(currentUser).once('value',function(users){
        var valueThatINeedToUseElsewhere = user.val().userName
        callback(valueThatINeedToUseElsewhere)
    })
}

on()是异步的,并立即返回,这意味着您的控制台日志将显示未定义的值。 传递给on()的回调仅在结果可用时才运行,并且不能保证会很快发生。 您只能在异步调用完成后使用它的值-在某些异步调用完成之前,请勿尝试使您的代码块。

如果只需要一次在某个位置使用该值,也可以考虑使用一次()代替on()。 加载所需的数据后,可以使用其返回的Promise链接其他工作。 它也是异步的(其他所有返回promise的方法也是如此)。

要了解有关Firebase API为何异步以及对您的应用意味着什么的更多信息,请阅读此博客

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM