AngularFire5中如何让Firestore获取的变量全局可用?
解决Firestore异步数据获取后无法在外部使用的问题
嘿,我完全懂你遇到的这个问题——异步操作的坑确实容易踩!你说得没错,问题根源就是Firestore的get()方法是异步的,它返回的是一个Promise,外部的console.log会在Promise完成前就执行,所以那时候this.myFirstName还没被赋值,自然是undefined。
下面给你几种靠谱的解决方式,按需选择就行:
方案1:用async/await简化异步逻辑
这是现在最常用的写法,能把异步代码写成同步的样子,可读性超高。你只需要把包含Firestore调用的函数标记为async,然后用await等待Promise完成:
async fetchMyProfile() { let documentRef = this.afs.collection('profiles').doc(this.userId); // 等待get()操作完成,拿到文档数据 const doc = await documentRef.ref.get(); this.myFirstName = doc.data().firstName; console.log(this.myFirstName); // 这里能正常输出值 // 所有需要使用这个数据的逻辑,都可以放在这里或者调用对应的函数 this.processFirstName(); } processFirstName() { // 这里可以放心使用this.myFirstName console.log(`我的名字是:${this.myFirstName}`); }
调用的时候直接执行this.fetchMyProfile()就行,await会确保后续代码在数据拿到后才执行。
方案2:把业务逻辑放到then回调里
如果不想用async/await,也可以把所有依赖这个数据的操作都放到then回调内部,或者封装成函数在回调里调用:
let documentRef = this.afs.collection('profiles').doc(this.userId); documentRef.ref.get() .then(doc => { this.myFirstName = doc.data().firstName; console.log(this.myFirstName); // 正常输出 // 在这里调用需要使用该数据的函数 this.doSomethingWithName(); }) doSomethingWithName() { // 这里能正常访问到已经赋值的this.myFirstName console.log(`使用名字做操作:${this.myFirstName}`); }
这种方式的核心是:所有依赖异步数据的代码,都要等待异步操作完成后再执行,而then回调就是Promise完成后的执行时机。
方案3:返回Promise让调用方处理
如果需要在多个地方复用这个数据获取逻辑,可以把获取数据的逻辑封装成一个返回Promise的函数,让调用的地方自己处理后续逻辑:
getMyFirstName() { let documentRef = this.afs.collection('profiles').doc(this.userId); return documentRef.ref.get().then(doc => { // 返回获取到的名字 return doc.data().firstName; }); } // 调用这个函数的时候 this.getMyFirstName().then(firstName => { console.log(firstName); // 在这里用firstName做任何你需要的操作 this.updateUIWithName(firstName); });
这样不管在哪里调用getMyFirstName(),都能通过then拿到最新的数据,灵活性很高。
总的来说,核心就是要记住:Firestore的数据库操作都是异步的,不能指望在异步操作外部直接同步拿到结果,必须把依赖数据的逻辑放在异步操作完成的回调里,或者用async/await等待操作完成。
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

