【问题标题】:How can we return data's from firebase queries with async await我们如何使用异步等待从 firebase 查询中返回数据
【发布时间】:2021-08-16 19:32:05
【问题描述】:

您好,我有一个用户集合的文档 ID 数组。我想从文档 id 的数组中检索给定 id 的用户集合的每个文档的对象中的所有用户数据的一些参数的用户数据数组。

但是在我当前的代码中,返回值是在解决承诺之前返回的,因此它是一个空数组。

有人可以详细解释一下如何实现这个异步调用,这是什么问题。

This is my code

export const getChatInfo = async chatIdsArray => {
  const userData = new Array();
  await chatIdsArray.forEach(async chatId => {
    const documentSnapshot = await firestore()
      .collection('users')
      .doc(chatId)
      .get();

    if (documentSnapshot.exists) {
      const {fname, lname, userImg} = documentSnapshot.data();
      userData.push({
        fname: fname,
        lname: lname,
        userImg: userImg,
      });
    }
    console.log(`userdata in getchatinfo inner : ${JSON.stringify(userData)}`); // this returns correct array
  });
  console.log(`userdata in getchatinfo outer : ${JSON.stringify(userData)}`); // this return an empty array
  return {userData};
};

【问题讨论】:

    标签: javascript google-cloud-firestore async-await


    【解决方案1】:

    forEach call 不返回承诺,因此await chatIdsArray.forEach( 毫无意义。

    我发现显式捕获承诺要容易得多,然后像这样使用单个 Promise.all()

    export const getChatInfo = async chatIdsArray => {
      const promises = chatIdsArray.map(chatId => firestore()
          .collection('users')
          .doc(chatId)
          .get();
      }).then((snapshots) => snapshots.map((documentSnapshot) => {
        if (documentSnapshot.exists) {
          const {fname, lname, userImg} = documentSnapshot.data();
          return { fname, lname, userImg  };
        }
      })
      return {Promise.all(userData)};
    };
    

    【讨论】:

    • 您好,您可以编辑您的代码吗,这是错误的,请详细说明 Promise.all 的工作原理。谢谢。
    • 如果您在使我的答案中的代码正常工作时遇到问题,请具体说明问题所在。有关Promise.all 的更多信息,我推荐:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
    【解决方案2】:

    您预计某些用户文档是空的,这就是(我假设)您不想使用.map() 的原因。不幸的是,.forEach() 不是异步的,所以在这里对您没有帮助。输入我最喜欢的模式之一 - .reduce() 链式 Promises 循环:

    export const getChatInfo = async chatIdsArray => {
       return chatIdsArray.reduce(async (resultArray, chatId) => {
        const documentSnapshot = await firestore()
          .collection('users')
          .doc(chatId)
          .get(); //documentSnopshot will be a PROMISE
        let outArray = await resultArray; //resultArray carries the reduce PROMISE
        if (documentSnapshot.exists) { //will wait for the above PROMISE
          const {fname, lname, userImg} = documentSnapshot.data();
          outArray = await outArray.concat({ // this will be a PROMISE
            fname: fname,
            lname: lname,
            userImg: userImg,
          });
        }
        return outArray; //either path, will be a PROMISE
    
        }, Promise.resolve([])); //this "empty" promise starts the chain
    };
    

    你也可以写成.then()chains

    export const getChatInfo = (chatIdsArray) => {
      return chatIdsArray.reduce((resultArray, chatId) => {
        return resultArray
          .then((outArray) => {
            return firestore().collection("users").doc(chatId).get();
          })
          .then((documentSnapshot) => {
            if (documentSnapshot.exists) {
              const { fname, lname, userImg } = documentSnapshot.data();
              return Promise.resolve( //the Promise.resolve() keeps the promise chain going
                resultArray.concat({
                  fname: fname,
                  lname: lname,
                  userImg: userImg
                })
              );
            }
            return Promise.resolve(resultArray); //will be a promise
          });
      }, Promise.resolve([]));
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-25
      • 2018-01-03
      • 1970-01-01
      • 1970-01-01
      • 2022-11-06
      • 2016-02-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多