Javascript Firebase-正在等待来自异步数据库调用的数据

Javascript Firebase-正在等待来自异步数据库调用的数据,javascript,reactjs,asynchronous,firebase-realtime-database,Javascript,Reactjs,Asynchronous,Firebase Realtime Database,我正在尝试通过2次数据库调用从firebase获取一些数据。 我的策略是仅为1个用户获取帐户,如下所示: 获取登录用户的所有帐号 获取帐户数组(及其所有数据)的新fetch调用 全数组调度呼叫 我的firebase结构是这样的 我的问题是,第二个fetch调用总是最后一个完成 export const fetchAccounts = () => { return (dispatch, getState) => { const accounts = [];

我正在尝试通过2次数据库调用从firebase获取一些数据。 我的策略是仅为1个用户获取帐户,如下所示:

  • 获取登录用户的所有帐号
  • 获取帐户数组(及其所有数据)的新fetch调用
  • 全数组调度呼叫
我的firebase结构是这样的

我的问题是,第二个fetch调用总是最后一个完成

export const fetchAccounts = () => {
   return (dispatch, getState) => {
      const accounts = [];
      const uid = getState().auth.uid;

      return database.ref(`users/${uid}/accounts`).once('value').then((snapshot) => {
         snapshot.forEach((element) => {
            database.ref(`accounts/${element.key}`).once('value').then((snapshot) => {
               accounts.push(snapshot.val());
               console.log('snapshot: ', accounts);
            })
         });
         console.log('Acc 1:', accounts);
      }).then(() => {
         console.log('Acc 2:', accounts)
      })

      // dispatch call with full array
   }
};

我正在从主文件调用操作

  reduxStore.dispatch(fetchAccounts()).then(()=>{
     renderApp();
  });
是否可以等待两个数据库调用完成,然后使用完全填充的数组调用调度函数?感谢您的建议。

您的第一个
then()
不会返回任何内容,因此第二个
then()
将立即启动,这就是您在控制台中看到的内容。但是,请求循环是异步的,尚未完成

创建一个承诺数组并使用它,这样第二个
then()
在循环中的请求全部完成之前不会触发

export const fetchAccounts = () => {
   return (dispatch, getState) => {
      const accounts = [];
      const uid = getState().auth.uid;

      return database.ref(`users/${uid}/accounts`).once('value').then((snapshot) => {
         const accountPromises =[];// array to store promises

         snapshot.forEach((element) => {
            // reference promise to pass into array
            const request = database.ref(`accounts/${element.key}`).once('value').then((snapshot) => {
               accounts.push(snapshot.val());
               console.log('snapshot: ', accounts);
            });
            // push request promise to array
            accountPromises.push(request)

         });
         console.log('Acc 1:', accounts);// accounts should still be empty here since requests are in progress
         // return promise that doesn't resolve until all requests completed
         return Promise.all(accountPromises);
      }).then(() => {
         // shouldn't fire until all the above requests have completed
         console.log('Acc 2:', accounts);
         return accounts // return array to use in next `then()`
      })

      // dispatch call with full array
   }
};
第一个
then()
不会返回任何内容,因此第二个
then()
将立即启动,这就是您在控制台中看到的。但是,请求循环是异步的,尚未完成

创建一个承诺数组并使用它,这样第二个
then()
在循环中的请求全部完成之前不会触发

export const fetchAccounts = () => {
   return (dispatch, getState) => {
      const accounts = [];
      const uid = getState().auth.uid;

      return database.ref(`users/${uid}/accounts`).once('value').then((snapshot) => {
         const accountPromises =[];// array to store promises

         snapshot.forEach((element) => {
            // reference promise to pass into array
            const request = database.ref(`accounts/${element.key}`).once('value').then((snapshot) => {
               accounts.push(snapshot.val());
               console.log('snapshot: ', accounts);
            });
            // push request promise to array
            accountPromises.push(request)

         });
         console.log('Acc 1:', accounts);// accounts should still be empty here since requests are in progress
         // return promise that doesn't resolve until all requests completed
         return Promise.all(accountPromises);
      }).then(() => {
         // shouldn't fire until all the above requests have completed
         console.log('Acc 2:', accounts);
         return accounts // return array to use in next `then()`
      })

      // dispatch call with full array
   }
};

谢谢!注释确实有助于理解逻辑:)请记住,如果这些请求中的任何一个失败
promise.all()
将无法解决,因此您需要添加额外的
catch()
以进行错误处理。非常感谢!这些注释确实有助于理解逻辑:)请记住,如果这些请求中的任何一个失败,promise.all()将无法解决,因此您需要添加额外的
catch()
以进行错误处理