如何用async/await实现Firestore查询完成后调用renderMessages?
解决Firestore异步查询后再调用渲染函数的问题
首先得明确:onSnapshot 是实时监听的异步方法,它会在初始获取所有文档,以及后续文档有变化时触发回调。你当前的问题是,回调还没处理完初始数据,renderMessages()就先执行了,导致listMessage是空的。
用async/await解决的核心思路是:把初始数据加载完成这个事件包装成一个Promise,等待这个Promise完成后再调用渲染函数。具体修改如下:
async getMessages(){ // 用Promise包裹初始快照的处理逻辑 const waitForInitialLoad = new Promise((resolve) => { this.removeListener = myFirestore .collection('messages') .doc(this.groupChatId) .collection(this.groupChatId) .onSnapshot( snapshot => { // 处理所有新增的消息(第一次快照会返回所有现有消息) snapshot.docChanges().forEach(change => { if (change.type === 'added') { this.listMessage.push(change.doc.data()) } }) // 初始数据处理完成,通知Promise可以继续了 resolve() }, err => { console.log(err) // 出错时也需要结束Promise,避免一直等待 resolve() }) }) // 等待初始数据加载并处理完成 await waitForInitialLoad // 现在listMessage已经有初始数据了,放心调用渲染函数 return this.renderMessages() }
额外优化:实时更新UI
因为onSnapshot是实时监听,后续有新消息进来时,你可能也需要自动更新UI。可以在消息添加后直接调用渲染函数:
snapshot.docChanges().forEach(change => { if (change.type === 'added') { this.listMessage.push(change.doc.data()) // 新消息进来后立刻重新渲染 this.renderMessages() } })
为什么这么改?
async关键字让getMessages变成异步函数,允许我们在里面用await- 我们创建的
Promise会等到第一次快照的回调执行完毕(也就是初始消息都塞进listMessage)才会resolve await会暂停函数执行,直到Promise完成,这样就保证了renderMessages()拿到的是已经填充好的listMessage
内容的提问来源于stack exchange,提问作者Vasu Ch
相关产品推荐
相关产品推荐

