如何使用typescript等待循环firebasecloud函数



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

在我的逻辑中,有时会返回一个空数组。status是实时数据库上的true。我认为它会在没有结束的情况下循环回来。

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);
}
}

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

您可以使用promise和Promise.all的组合。您可以使用标准的for-of

承诺

您可以将realTimeDB数据返回转化为承诺。承诺文档

const rtDbPromise = (loc: QueryDoc): Promise<UserData | null> => {
const data = loc.data();
return new Promise((resolve, reject) => {
rtDb.ref(data.uid).once("value", (snap: Snap) => {
try {
if (snap.val().status) {
resolve(data);
} else {
resolve(null);
}
} catch (e) {
reject(e);
}
});
});
};

承诺所有

然后你可以将所有的Promise添加到一个数组中,并使用Promise.all

type UserData = { uid: string };
type Snap = { val: () => { status: boolean } };
type QueryDoc = { data: () => UserData };
type MockRtDb = {
ref: (
uid: string
) => {
once: (type: "value", callback: (snap: Snap) => void) => Promise<void>;
};
};
async function getOnlineUsers(): Promise<UserData[]> {
const rtDb = {} as MockRtDb;
// Create the async call here (Promise)
const rtDbPromise = (loc: QueryDoc): Promise<UserData | null> => {
const data = loc.data();
return new Promise((resolve, reject) => {
rtDb.ref(data.uid).once("value", (snap: Snap) => {
try {
if (snap.val().status) {
resolve(data);
} else {
resolve(null);
}
} catch (e) {
console.log(e);
// This will throw an error. If any promises fail, Promise.all will throw as well.
// Maybe return null if you don't want errors. Read the docs for more info
reject(e);
}
});
});
};
const dataArray: QueryDoc[] = [];
const promise: Promise<UserData | null>[] = [];
for (const data of dataArray) {
promise.push(rtDbPromise(data));
}
const dataWithNulls: (UserData | null)[] = await Promise.all(promise);
// Filter out the nulls
return dataWithNulls.filter((item) => item !== null);
}
const onlineUsers = await getOnlineUsers();

相关内容

  • 没有找到相关文章

最新更新