首页 > 解决方案 > 无法理解 firebase 中的 doc().get()

问题描述

我在理解为什么我的代码不起作用时遇到了一些麻烦。我正在尝试从 react-native 项目中的 firebase 读取数据。我可以很好地阅读它,但我无法将数据设置为任何变量。

这是我的代码。

let tmp;
    let userRef = firebase.firestore().collection("Users");

    userRef.doc(this.state.FirstName).get().then((document) => { 
      tmp = document.data().FirstName;
      alert(tmp);
    })
    .catch((errorMsg) => {
      alert(errorMsg);
    })
    alert("tmp Data: " + tmp);
  };

问题是,如果我tmp在函数内部发出警报,它会按预期显示 FirstName 变量。但是当我在函数之外发出警报时tmp,它显示未定义。我似乎无法理解为什么这不起作用,如果有人能告诉我我在这里做错了什么,我将不胜感激。

标签: javascriptfirebasereact-nativegoogle-cloud-firestorereact-native-android

解决方案


这是完全正常的。发生这种情况是因为如果您将alert块放在外部,那么它将在块之前执行,tmp并且未初始化。FirstName从数据库(函数)中获取的get()代码在另一个线程中执行一些代码,并且您的原始线程继续进行而不等待它完成。当另一个线程完成执行时,块内的代码将被执行。您可以通过在块之前、内部和之后添加 s 来验证此行为,alert以查看执行顺序。要了解更多信息,请阅读异步操作承诺

为什么这一切?为什么要get()在另一个线程中执行一些代码?简而言之,因为它使用网络访问 Firebase 数据库,并且可能需要一些时间才能得到响应。如果get()在同一个调用线程中执行“网络代码”,那么从主线程(UI 线程)调用它将使您的 UI 无响应,直到响应返回。因此,相反,get()将“网络代码”分派给另一个线程,并promise在“网络代码”完成执行之前立即返回一个对象。你用那个promise对象来指定你想要在结果到达时如何处理它。这样,调用线程继续执行,不需要等待,并且在调用线程是UI线程的情况下(通常是这种情况),这意味着你的UI总是响应式的。


推荐阅读