我正在编写一个由两个数据库构建的评论系统:一个包含评论者的文本和 ID,然后用于访问第二个数据库以检索并动态显示发布者的个人资料信息(pfp 和显示名称)对于他们提交的每条评论。
useEffect() Hook 内的函数返回 Promises 数组。我一直在试图找出访问这些 Promise 中的值的方法,但到目前为止还没有成功。我知道 .then()
专门用于此目的,但我不明白在这种情况下如何以及在何处正确应用它。
import React, { useEffect, useState, Fragment } from 'react'
import firebase from './firebase'
export const Comments = () => {
const [cred, setCred] = useState('')
const [comment, setComment] = useState('')
const [allComments, setAllComments] = useState(null)
useEffect(() => {
// grab the database containing poster ID
// & text of each single comment by it's name and then map over it
firebase.getData('text&ID').onSnapshot(snapshot => setAllComments([...snapshot.docs.map(async (doc) => {
// using the poster ID,
// access the 'users' DB that contains the avatar & name fields
let comment = doc.data().content
let poster = await firebase.getData('users').doc(doc.data().posterID).get()
let name = poster.data().name
let avatar = poster.data().avatar
// returning an object of all the data we want to display for each comment
return ({
name: name,
avatar: avatar,
comment: comment
})
})]))
// if user exists, set state to their credentials
firebase.isInitialized().then(val => setCred(val))
}, [])
return allComments && <Fragment>
// submit the comment to the text&DB collection with text, poster ID and text
{cred && <form onSubmit={(e) => {
e.preventDefault()
firebase.addComment('text&ID', cred.uid, comment).then(console.log('comment sent!')).then(setComment(''))
}}>
<input
type="text"
value={comment}
name="text"
placeholder="comment..."
onChange={e => { setComment(e.target.value) }}
required
/>
<br />
<button >Post</button>
</form>}
<ul>
// the plan was to map over allComments
// and return an <li> with all the display info
// but logging to console displays THE array of Promises
// that I want to access
{console.log(allComments)}
</ul>
</Fragment>
}
非常欢迎任何和所有的意见。
这是 console.log 输出:
[Promise]
0: Promise
__proto__: Promise
[[PromiseStatus]]: "resolved"
[[PromiseValue]]: Object
avatar: "https://i.imgur.com/v4ImnVE.jpg"
comment: "no halo"
name: "polnareff"
__proto__: Object
length: 1
__proto__: Array(0)
最佳答案
async function表示一个异步函数
,实际上返回一个Promise
,以便在函数内的所有代码都已执行时收到通知。
因此,在您的代码中 [...snapshot.docs.map(async ...)]
将返回一个 Promise
数组。顺便说一句,您不需要使用解构运算符 ...
,您可以直接使用 snapshot.docs.map
它将返回一个新数组。
您可以使用Promise.all等到所有 promise 都得到解决,然后更新状态变量allComments
。
这是您的效果代码:
useEffect(() => {
firebase.getData('text&ID').onSnapshot(snapshot => {
const commentPromises = snapshot.docs.map(async (doc) => {
const {posterId} = doc.data();
const poster = await firebase.getData('users').doc(posterID).get();
const {avatar, name, content: comment} = poster.data()
return {name, avatar, comment};
});
Promise.all(commentPromises)
.then(setAllComments)
.catch(...);
});
firebase.isInitialized()
.then(val => setCred(val))
.catch(...);
});
关于javascript - 如何访问 Promise 的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58670639/