【问题标题】:How do I properly use async and await when getting data from my firebase db?从我的 firebase 数据库获取数据时,如何正确使用 async 和 await?
【发布时间】:2021-04-06 05:00:36
【问题描述】:

我需要从我在 firebase 中的实时数据库中获取 json 数据并为其设置一个变量。我尝试在下面的代码中这样做

useEffect(() => {
  let database = firebase.database();
  database.ref().on('value', async (snapshot) => {

    await setQuestions(snapshot.val());
    console.log('questions here ', questions)
  }) 
},[]);

console.log 在此处输出问题 null,而不是记录实际数据。我知道这是一个涉及行执行顺序的问题,因为我已经证明我实际上是从数据库中提取数据。它只是没有完成将它拉到我需要的地方。 据我了解, await 将在 async 块内停止执行,直到带有 await 的代码行完成。然而,这并没有发生。所以要么我误解了异步函数的工作原理,要么我没有将 async 或 await 关键字放在我需要的地方。任何帮助表示赞赏。

编辑:问题已定义。在我的代码中如下所示

const [questiona, setQuestions] = useState(null);

【问题讨论】:

  • 您是否检查过 setQuestions 正在返回一个承诺?
  • 是否在 setQuestions 中设置了 questiona?
  • questiona 似乎没有定义。
  • @controlaltdel questiona 已定义。我刚刚编辑了原始帖子以显示我如何初始化它。我将其设置为 null,这解释了为什么当我尝试打印问题时 console.log 返回 null。问题是我似乎无法在需要时将问题设置为 snapshot.val()。

标签: javascript node.js firebase firebase-realtime-database


【解决方案1】:

await 无效,除非 RHS 上的值是一个承诺。

setQuestions 我认为是useState 钩子的集合部分。它不返回承诺。

如果确实如此,那么 questiona 变量(我假设它是该挂钩的数据部分)无论如何都不会在当前范围内更新。)


如果您想查看 questiona 是什么,请将其记录在您正在使用的 React 组件的下一次渲染中。


const [questiona, setQuestions] = useState(someDefaultValue);

console.log(questiona);

useEffect(() => {
  let database = firebase.database();
  database.ref().on(
    'value', 
    (snapshot) => setQuestions(snapshot.val())
  ); 
},[]);

【讨论】:

  • RHS 表示我假设的反应挂钩状态?我以与您相同的方式初始化questiona,只是我将其设置为null,这解释了为什么控制台记录为null。那么,既然awaitasync 在这里没有用,我如何将questiona 设置为snapshot.val() 以便questiona 在我需要使用它时不为空?
  • RHS 表示右手边
  • 你已经设置好了(或者我在这个例子中)。 (这假设回调函数确实被调用并且snapshot.val() 返回一个有用的值)。当然,您需要在第一次渲染时将questiona 视为null(例如显示加载消息)。
  • 好的,我明白你的意思了。它需要 3 次渲染才能设置为我需要的。另外,快速提问。我在 useEffect 方法之外放置了另一个 console.log。所以现在我的代码中有原始的 console.log 和新的。输出是``` null, null, 最后设置为DB的内容,这里的问题是null ``` 为什么方法里面的console.log显示questiona为null,但是外面的console.log显示的是内容数据库?
  • useEffect 内部,它在组件第一次渲染时运行(当它为空时),然后在重新渲染时再次运行并且依赖项发生了变化……因为你的依赖列表是空的,永远不会。
【解决方案2】:

上述代码中的问题是,当我们将任何函数声明为异步时,它会返回一个 Promise。

您需要在 useEffect 之外创建一个单独的异步函数,并从 useEffect 中调用它。

【讨论】:

  • 为什么这是个问题?如果第二个参数返回一个promise,database.ref().on() 有问题吗?
猜你喜欢
  • 2020-02-02
  • 1970-01-01
  • 2020-09-09
  • 2020-12-02
  • 2020-05-06
  • 2021-02-16
  • 2020-12-11
  • 1970-01-01
  • 2022-01-03
相关资源
最近更新 更多