Javascript 从firebase db获取数据时,如何正确使用async和Wait?

Javascript 从firebase db获取数据时,如何正确使用async和Wait?,javascript,node.js,firebase,firebase-realtime-database,Javascript,Node.js,Firebase,Firebase Realtime Database,我需要从firebase中的实时数据库中获取json数据,并为其设置一个变量。我试着在下面的代码中这样做 useEffect(() => { let database = firebase.database(); database.ref().on('value', async (snapshot) => { await setQuestions(snapshot.val()); console.log('questions here ', question

我需要从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将在异步块内停止执行,直到包含await的代码行完成为止。然而,这并没有发生。因此,要么我误解了异步函数的工作原理,要么我没有将async或wait关键字放在需要的地方。感谢您的帮助

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

const [questiona, setQuestions] = useState(null);
除非RHS上的值是承诺,否则等待无效

我假设,setQuestions是useState钩子的set部分。它没有回报一个承诺

如果它这样做了,那么问题A变量(我假设是该钩子的数据部分)无论如何都不会在当前范围内更新

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


上面代码中的问题是,当我们将任何函数声明为async时,它将返回一个承诺


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

是否检查了setQuestions是否返回承诺?questiona是否在setQuestions中设置?questiona似乎没有定义。@controlaltdel questiona已定义。我刚刚编辑了原始帖子,以显示我是如何初始化它的。我将其设置为null,这解释了为什么我尝试打印问题A时console.log返回null。问题是,我似乎无法在需要时将questiona设置为snapshot.val。为什么会出现这样的问题?如果第二个参数返回承诺,database.ref.on是否有问题?RHS表示我假设的react钩子状态?我以与您相同的方式初始化了questiona,只是将其设置为null,这解释了控制台记录为null的原因。既然await和async在这里没有用处,我该如何将questiona设置为snapshot.val,以便在需要使用它时questiona不为null?RHS表示右侧,您可以将其设置为您已经设置的状态或本例中的状态。这假设回调函数确实被调用,snapshot.val返回一个有用的值。当然,你需要解释问题a在第一次呈现时为空,例如显示加载消息。好的,我现在明白你的意思了。需要3次渲染才能将其设置为我需要的状态。还有,快速提问。我将另一个console.log放在useEffect方法的正外部。现在我的代码中有了原来的console.log和新的console.log。输出为``null,null,最后设置为DB的content,questions here null``为什么方法内部的console.log会将questiona显示为null,而外部的console.log会将DB的内容显示给它?内部的useEffect它会在组件第一次呈现为null时运行,然后在重新呈现时再次运行,并且依赖项会发生变化……而且由于依赖项列表为空,这永远不会。
const [questiona, setQuestions] = useState(someDefaultValue);

console.log(questiona);

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