首页 > 解决方案 > 如何访问 Promise 的值?

问题描述

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

钩子内的函数useEffect()返回一个 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)

标签: javascriptreactjsfirebaseasynchronousreact-hooks

解决方案


Moved from comments to answer as it proved to answer the question.

I suggest looking at promise.all()

It basically takes in a array of promises.

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

it might be what you are looking for.

If this gives you the correct output just replace the console.log with result.map(item => {<li>{item.comment}</li>}) etc.


推荐阅读