【发布时间】:2021-07-12 15:20:09
【问题描述】:
我是 JS 的“async/await”方面的新手,我正在尝试了解它是如何工作的。
我得到的错误是以下代码的第 10 行。我已经创建了一个 firestore 数据库,并试图从 Collection 'rooms' 中监听并获取某个文档。我正在尝试从 doc 'joiner' 获取数据并使用该数据来更新其他元素的 innerHTML。
// References and Variables
const db = firebase.firestore();
const roomRef = await db.collection('rooms');
const remoteNameDOM = document.getElementById('remoteName');
const chatNameDOM = document.getElementById('title');
let remoteUser;
// Snapshot Listener
roomRef.onSnapshot(snapshot => {
snapshot.docChanges().forEach(async change => {
if (roomId != null){
if (role == "creator"){
const usersInfo = await roomRef.doc(roomId).collection('userInfo');
usersInfo.doc('joiner').get().then(async (doc) => {
remoteUser = await doc.data().joinerName;
remoteNameDOM.innerHTML = `${remoteUser} (Other)`;
chatNameDOM.innerHTML = `Chatting with ${remoteUser}`;
})
}
}
})
})
})
但是,我得到了错误:
Uncaught (in promise) TypeError: Cannot read property 'joinerName' of undefined
如果我将第 10-12 行更改为:
remoteUser = await doc.data();
remoteNameDOM.innerHTML = `${remoteUser.joinerName} (Other)`;
chatNameDOM.innerHTML = `Chatting with ${remoteUser.joinerName}`;
我得到同样的错误。
我目前的理解是 await 将等待行/函数完成后再继续前进,因此 remoteUser 在尝试调用它之前不应为空。我会提到,有时代码运行良好,并且更新了 DOM 元素并且没有控制台错误。
我的问题:我是否错误地考虑了 async/await 调用?这不是我应该如何从 Firestore 获取文件的方式吗?最重要的是,为什么它似乎只在某些时候起作用?
【问题讨论】:
-
这能回答你的问题吗? Using async/await with a forEach loop
-
很难说,因为代码不可运行(请参阅minimal reproducible example——您可以模拟 API 调用),但看起来您在循环中有竞争条件。每次迭代都不会等待下一次,它们都试图改变相同的 DOM 节点,所以它是不确定的。即使它是确定性的,也很难推断出您的意图,因为最后一个元素对
innerHTML的调用会覆盖之前的所有元素。 -
您能否也发布您的 Firestore 文档的屏幕截图?
标签: javascript firebase asynchronous google-cloud-firestore async-await