如何使用typescript等待for循环中的firebase云函数

如何使用typescript等待for循环中的firebase云函数,typescript,google-cloud-functions,Typescript,Google Cloud Functions,我有一个从firestore DB查找用户的查询。然后我需要找到哪个用户在线或不在线。为此,我使用了构建状态(实时数据库) 在我的逻辑中,有时返回一个空数组状态在实时数据库上为真。我认为它会在没有完成循环的情况下返回 const users: Array<any> = []; await asyncForEach(query.docs, async (loc: any) => { const data = loc.data(); await rtDb.ref(data

我有一个从firestore DB查找用户的查询。然后我需要找到哪个用户在线或不在线。为此,我使用了构建状态(实时数据库)

在我的逻辑中,有时返回一个空数组<代码>状态在实时数据库上为
。我认为它会在没有完成循环的情况下返回

const users: Array<any> = [];

await asyncForEach(query.docs, async (loc: any) => {
  const data = loc.data();
  await rtDb.ref(data.uid).once('value', function (snap) {
    if (snap.val().status === true) {
      users.push(data);
    }
  }).catch((e) => {
    console.log(`${e}`)
  });
});

return users;


async function asyncForEach(array: Array<any>, callback: Function) {
  for (let index = 0; index < array.length; index++) {
    await callback(array[index], index, array);
  }
}
const用户:数组=[];
等待asyncForEach(query.docs,async(loc:any)=>{
const data=loc.data();
等待rtDb.ref(data.uid).once('value',函数(snap){
if(snap.val().status==true){
推送(数据);
}
}).catch((e)=>{
console.log(`${e}`)
});
});
返回用户;
异步函数asyncForEach(数组:数组,回调:函数){
for(让index=0;index
很难说错误在哪里。如果您得到的是空数组,您确定
loc.data()
没有抛出错误吗?或者有其他错误阻止推送发生

您可以使用承诺和
承诺的组合。您可以使用标准的
来执行

承诺 您可以将实时数据库数据返回变成承诺

constrtdbpromise=(loc:QueryDoc):Promise=>{
const data=loc.data();
返回新承诺((解决、拒绝)=>{
rtDb.ref(data.uid).once(“值”,(snap:snap)=>{
试一试{
if(snap.val().status){
解析(数据);
}否则{
解析(空);
}
}捕获(e){
拒绝(e);
}
});
});
};
答应所有人 然后,您可以将所有承诺添加到一个数组中并使用。循环

type UserData={uid:string};
类型Snap={val:()=>{status:boolean}};
键入QueryDoc={data:()=>UserData};
类型MockRtDb={
参考:(
uid:字符串
) => {
一次:(输入:“值”,回调:(捕捉:捕捉)=>void)=>Promise;
};
};
异步函数getOnlineUsers():Promise{
常量rtDb={}作为MockRtDb;
//在此处创建异步调用(承诺)
const rtDbPromise=(loc:QueryDoc):Promise=>{
const data=loc.data();
返回新承诺((解决、拒绝)=>{
rtDb.ref(data.uid).once(“值”,(snap:snap)=>{
试一试{
if(snap.val().status){
解析(数据);
}否则{
解析(空);
}
}捕获(e){
控制台日志(e);
//这将抛出一个错误。如果任何承诺失败,则Promise.all也将抛出。
//如果不希望出现错误,可能会返回null。有关详细信息,请阅读文档
拒绝(e);
}
});
});
};
常量数据数组:QueryDoc[]=[];
const promise:promise[]=[];
for(数据阵列的常量数据){
promise.push(rtDbPromise(data));
}
const dataWithNulls:(UserData | null)[]=等待承诺.all(承诺);
//过滤掉空值
返回dataWithNulls.filter((item)=>item!==null);
}
const onlineUsers=等待getOnlineUsers();

很难说错误在哪里。如果您得到的是空数组,您确定
loc.data()
没有抛出错误吗?或者有其他错误阻止推送发生

您可以使用承诺和
承诺的组合。您可以使用标准的
来执行

承诺 您可以将实时数据库数据返回变成承诺

constrtdbpromise=(loc:QueryDoc):Promise=>{
const data=loc.data();
返回新承诺((解决、拒绝)=>{
rtDb.ref(data.uid).once(“值”,(snap:snap)=>{
试一试{
if(snap.val().status){
解析(数据);
}否则{
解析(空);
}
}捕获(e){
拒绝(e);
}
});
});
};
答应所有人 然后,您可以将所有承诺添加到一个数组中并使用。循环

type UserData={uid:string};
类型Snap={val:()=>{status:boolean}};
键入QueryDoc={data:()=>UserData};
类型MockRtDb={
参考:(
uid:字符串
) => {
一次:(输入:“值”,回调:(捕捉:捕捉)=>void)=>Promise;
};
};
异步函数getOnlineUsers():Promise{
常量rtDb={}作为MockRtDb;
//在此处创建异步调用(承诺)
const rtDbPromise=(loc:QueryDoc):Promise=>{
const data=loc.data();
返回新承诺((解决、拒绝)=>{
rtDb.ref(data.uid).once(“值”,(snap:snap)=>{
试一试{
if(snap.val().status){
解析(数据);
}否则{
解析(空);
}
}捕获(e){
控制台日志(e);
//这将抛出一个错误。如果任何承诺失败,则Promise.all也将抛出。
//如果不希望出现错误,可能会返回null。有关详细信息,请阅读文档
拒绝(e);
}
});
});
};
常量数据数组:QueryDoc[]=[];
const promise:promise[]=[];
for(数据阵列的常量数据){
promise.push(rtDbPromise(data));
}
const dataWithNulls:(UserData | null)[]=等待承诺.all(承诺);
//过滤掉空值
返回dataWithNulls.filter((item)=>item!==null);
}
const onlineUsers=等待getOnlineUsers();

@BloodLoss。希望一切顺利well@BloodLoss当然可以。希望一切顺利