我正在制作的刮板有一条注册路线来开始刮板过程。由于抓取过程非常漫长,因此我决定创建另一条路由,我的前端将每15秒请求一次路由以获取数据。我遇到的问题是,即使抓取完成后,获取数据的路径仍返回空对象。实际上,它应该返回了已抓取的数据,而没有返回404错误(请参阅下面的代码)。如果出现问题,我会添加一些额外的代码。
const scraper = async (email, password) => {
let grades = [[], [], [], []];
let category_weights = [];
try {
// try to scrape website
// this block of code contains await functions
} catch (e) {
console.log(e);
return;
} finally {
return {
grades,
category_weights
};
}
};
let result;
app.post("/api/register", (req, res) => {
result = scraper(req.body.email, req.body.password);
res.sendStatus(200);
});
app.get("/api/data", (req, res) => {
console.log(result["grades"]); // undefined
console.log(JSON.stringify(result, null, 4)); // {}
result.hasOwnProperty("grades") ? res.json(result) : res.sendStatus(404);
});
答案 0 :(得分:1)
该代码正在返回 404 状态代码,因为result
是Promise
,并且没有grades
属性。
您必须等到诺言完成。您可以使用await
。这样,刮板完成后,对/api/data
的调用将返回数据,而不是 404 状态码。
为了避免超时问题,您可以增加该特定路由的超时时间:
req.setTimeout(1000 * 60 * 5); // or whatever value you want
或者只要点击/api/register
就结束请求,然后运行scraper函数,等待结果。
app.post("/api/register", async(req, res) => {
res.sendStatus(200);
try {
result = await scraper(req.body.email, req.body.password);
} catch(e) {
console.log('Scraper failed');
}
});
app.get("/api/data", (req, res) => {
console.log(result["grades"]); // undefined
console.log(JSON.stringify(result, null, 4)); // {}
result.hasOwnProperty("grades") ? res.json(result) : res.sendStatus(404);
});
这证明JSON.stringify
上的Promise
将返回{}
console.log(JSON.stringify(new Promise(() => {}), null, 4)); // {}