Javascript 如何查询firebase并输出异步结果?
今天我到处都在找,弄得头昏眼花,真的不知道该怎么办 我正在尝试做一些听起来简单的事情。然而,异步工作流让我崩溃了Javascript 如何查询firebase并输出异步结果?,javascript,node.js,firebase,google-cloud-firestore,google-cloud-functions,Javascript,Node.js,Firebase,Google Cloud Firestore,Google Cloud Functions,今天我到处都在找,弄得头昏眼花,真的不知道该怎么办 我正在尝试做一些听起来简单的事情。然而,异步工作流让我崩溃了 从Firestore中的爬网作业中查找每个ID 获取其他集合中这些ID的所有文档 将输出添加到数组中 返回数组的输出 因为所有的东西都是异步的,所以我一直停留在第2和第3条上,因为第4条的执行速度比异步代码要快 我的大问题是,我该如何处理 以下是我的全部功能: exports.publicOutput = functions .region("us-central1&q
exports.publicOutput = functions
.region("us-central1")
.runWith(runtimeOpts)
.https.onRequest(async (req, res) => {
const projectAlias = req.query.projectalias;
const apiKey = req.query.apikey;
let status = 404;
let data = {
Message:
"Unauthorized access! Please provide the correct authentication data.",
};
let response = data;
let scrapeStorage = [];
// check if credentials are provided
if (!projectAlias || !apiKey) {
return res.status(status).send(response);
}
// when both items provided execute this
if (projectAlias && apiKey) {
const snapshot = await db
.collection("AdaProjects")
.where("projectAlias", "==", projectAlias)
.where("hasAccess", "array-contains", apiKey)
.limit(1)
.get();
if (snapshot.empty) {
return res.status(status).send(response);
}
if (!snapshot.empty) {
snapshot.forEach((doc) => {
projectData = doc.data();
});
status = 200;
}
const crawlJobIDs = projectData.crawlJobs;
let scrapeIDs = [];
crawlJobIDs.forEach(async (jobID) => {
const snapshot = await db
.collection("scrapes")
.where("crawlJobID", "==", jobID)
.get();
if (snapshot.empty) {
console.log("not found jobID", jobID);
return;
}
snapshot.forEach((doc) => {
scrapeIDs.push(doc.id);
console.log(scrapeIDs); // here everything is fine. But this outputs (logically) after "DONE"
});
});
response = scrapeIDs;
}
console.log("DONE");
return res.status(status).send(response);
});
我还尝试将所有内容放入函数中,并在函数结束之前等待它
async function getAllScrapeIDs(crawlJobIDs) {
let someData = [];
try {
crawlJobIDs.forEach(async (jobID) => {
const snapshot = await db
.collection("scrapes")
.where("crawlJobID", "==", jobID)
.get();
if (snapshot.empty) {
console.log("not found jobID", jobID);
return;
}
snapshot.forEach((doc) => {
someData.push(doc.id);
});
});
} catch (error) {
console.log(error);
return null;
}
return someData;
}
// and then later in the code
const crawlJobIDs = projectData.crawlJobs;
response = await getAllScrapeIDs(crawlJobIDs);
响应仍然为空,因为异步代码仍然没有更新
我还尝试在没有async/await的情况下编写所有内容,并应用了.then.catch选项。输出相同。我的函数在用我想要输出的数据填充数组之前完成
我发现这是一个令人费解的问题,因为这部分
const crawlJobIDs=projectData.crawlJobs代码>实际上正在工作。可能是因为它只搜索一项?在forEach循环中使用async/await不是一个好主意,请参阅和
您应使用以下方法:
const crawlJobIDs = projectData.crawlJobs;
let scrapeIDs = [];
let promises = [];
crawlJobIDs.forEach((jobID) => {
promises.push(db
.collection("scrapes")
.where("crawlJobID", "==", jobID)
.get());
});
const snapshot = await Promise.all(promises);
// snapshot is an Array of QuerySnapshots
// You need to loop on this Array
snapshot.forEach(querySnapshot => {
querySnapshot.forEach(documentSnapshot => {
scrapeIDs.push(documentSnapshot.id);
});
});
if (!snapshot.empty) {
const doc = snapshot.docs[0];
projectData = doc.data();
status = 200;
}
我允许您管理快照为空的情况
此外,您还可以使用另一种方法
if (!snapshot.empty) {
snapshot.forEach((doc) => {
projectData = doc.data();
});
status = 200;
}
由于您知道查询快照中最多有一个文档(由于限制(1)
),请执行以下操作:
const crawlJobIDs = projectData.crawlJobs;
let scrapeIDs = [];
let promises = [];
crawlJobIDs.forEach((jobID) => {
promises.push(db
.collection("scrapes")
.where("crawlJobID", "==", jobID)
.get());
});
const snapshot = await Promise.all(promises);
// snapshot is an Array of QuerySnapshots
// You need to loop on this Array
snapshot.forEach(querySnapshot => {
querySnapshot.forEach(documentSnapshot => {
scrapeIDs.push(documentSnapshot.id);
});
});
if (!snapshot.empty) {
const doc = snapshot.docs[0];
projectData = doc.data();
status = 200;
}
这太棒了,雷诺。它立即奏效了。最后一个注释也是一个很好的注释,可以删除一些代码行。还感谢您的参考。我将在forEach循环中使用不异步的精神节点。我想知道这里发生了什么crawlJobIDs.forEach((jobID)=>{promises.push(db.collection(“scrapes”).where(“crawlJobID”,“==”,jobID.get());})代码>--是不是icwconst snapshotGroup=wait Promise.all(promises)代码>。在继续并使用snapshotGroup循环它们之前,它会等待所有承诺都完成?是的,Promise.all()
方法将一个承诺数作为输入,并返回一个承诺数,该承诺数解析为输入承诺数的结果数组。“请参阅一分钟前阅读的内容。”。我将阅读更多关于这个及其用例的内容。再次感谢您的快速回复,并在我的周末开始前节省了时间:)@arnoud,已经这么做了!事实上,他马上就这么做了。还将其标记为答案。也许需要时间?