Javascript 我们如何返回数据';使用异步等待从firebase查询中删除
嗨,我有一个用户集合的文档id数组。我想从文档id数组中为给定id的用户集合的每个文档检索一个用户数据数组,其中包含对象中所有用户数据的一些参数 但在我当前的代码中,返回值是在承诺得到解决之前返回的,因此它是一个空数组 有人能给我解释一下如何实现这个异步调用,以及这个调用有什么问题吗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
这是我的代码
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