如何获取Promise的价值



我正在编写一个由两个数据库构建的注释系统:一个数据库包含注释的文本和ID,然后用于访问第二个数据库以检索&动态显示发布者提交的每条评论的个人资料信息(pfp和显示名称(。

useEffect()钩子内的函数返回一个Promises数组。我一直在想办法访问这些承诺中的价值观,但到目前为止都无济于事。我知道.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函数表示一个asynchronous 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(...);
});

从注释转移到答案,因为事实证明它可以回答问题。

我建议查看promise.al((

它基本上接受了一系列的承诺。

Promise.all([Promise1, Promise2, Promise3]) .then(result) => { console.log(result) }) .catch(error => console.log(Error in promises ${error}))

这可能就是你想要的。

如果这给了您正确的输出,只需将console.log替换为result.map(item => {<li>{item.comment}</li>})

最新更新