在Firebase中难以理解doc()。get()

时间:2019-07-17 01:49:31

标签: javascript firebase react-native google-cloud-firestore react-native-android

我在理解为什么我的代码无法正常工作时遇到了一些麻烦。我正在尝试从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发出警报时,它显示为未定义。我只是似乎无法绕开为什么这行不通的想法,如果有人可以告诉我我在这里做错了什么,我将不胜感激。

1 个答案:

答案 0 :(得分:3)

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

为什么所有这些?为什么get()在另一个线程中执行某些代码?简而言之,因为它使用网络访问Firebase数据库,并且可能需要一些时间才能返回响应。如果get()在同一调用线程中执行“网络代码”,则从主线程(UI线程)进行调用将使您的UI无响应,直到响应返回。因此,相反,get()将“网络代码”调度到另一个线程,并甚至在“网络代码”完成执行之前立即返回promise对象。您可以使用该promise对象指定结果到达时要执行的操作。这样,调用线程将继续执行,而无需等待,并且在调用线程是UI线程的情况下(通常是这种情况),这意味着您的UI始终是响应式的。