Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/435.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我们如何返回数据';使用异步等待从firebase查询中删除_Javascript_Google Cloud Firestore_Async Await - Fatal编程技术网

Javascript 我们如何返回数据';使用异步等待从firebase查询中删除

Javascript 我们如何返回数据';使用异步等待从firebase查询中删除,javascript,google-cloud-firestore,async-await,Javascript,Google Cloud Firestore,Async Await,嗨,我有一个用户集合的文档id数组。我想从文档id数组中为给定id的用户集合的每个文档检索一个用户数据数组,其中包含对象中所有用户数据的一些参数 但在我当前的代码中,返回值是在承诺得到解决之前返回的,因此它是一个空数组 有人能给我解释一下如何实现这个异步调用,以及这个调用有什么问题吗 这是我的代码 export const getChatInfo = async chatIdsArray => { const userData = new Array(); await chatId

嗨,我有一个用户集合的文档id数组。我想从文档id数组中为给定id的用户集合的每个文档检索一个用户数据数组,其中包含对象中所有用户数据的一些参数

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

有人能给我解释一下如何实现这个异步调用,以及这个调用有什么问题吗

这是我的代码

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};
};
没有返回承诺,因此
等待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)};
};

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

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
};
您也可以将其写成
。然后()

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([]));
};

您好,您可以编辑您的代码吗?它是错误的,请详细说明Promise.all的工作原理。谢谢。如果您在我的答案中的代码工作时遇到问题,请具体说明问题所在。有关Promise.all的更多信息,我建议:所有已解决的promises返回null