意外返回异步/等待功能

时间:2019-03-09 20:45:55

标签: javascript node.js express async-await

我正在制作的刮板有一条注册路线来开始刮板过程。由于抓取过程非常漫长,因此我决定创建另一条路由,我的前端将每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);
});

1 个答案:

答案 0 :(得分:1)

该代码正在返回 404 状态代码,因为resultPromise,并且没有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)); // {}