【问题标题】:Waiting for response after clickling点击后等待回复
【发布时间】:2017-11-09 17:10:49
【问题描述】:

我点击按钮,然后发送 ajax 请求并更改输入隐藏值。 如何等待答案并追踪隐藏字段的变化?

我曾尝试过让“睡眠”并获取事件,但有时你会得到错误的数据,因为请求很长。

http.createServer(async (req, res) => {
if (req.url === '/') {
    if (req.method === 'GET') {
        res.writeHead(200, {
            'content-type': 'text/html; charset=utf-8',
            'cache-control': 'public,max-age=31536000',
        });
        res.end(fs.readFileSync(__dirname + '/templates/index.html'));
        return;
    } else if (req.method === 'POST') {

        let body = '';
        await req.on('data', (data) => body += data);

        body = qs.parse(body);

        let url = body.url;

        const browser = await puppeteer.launch();
        const page = await browser.newPage();
        await page.goto(url);

        let count = (selector) => page.evaluate((selector) => {
            return (document.querySelectorAll(selector)).length;
        }, selector);

        let sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

        const countM = await count(MSEL),
            countS = await count(SSEL);
        console.log(countS, countM);

        let click = (selector, number) => page.click(`${selector}:nth-child(${number})`);

        let data = [];

        for (let i = 1; i <= countS; i++) {
            await click(SSEL, i);
            sleep(SLEEP);

            for (let j = 1; j <= countM; j++) {
                await click(MSEL, j);
                sleep(SLEEP);

                const info = await page.evaluate(() => {
                    return {
                        val: document.getElementById('val').value,
                        cc: document.getElementById('cc').value
                    };
                });
                data.push(info);
            }
        }
    }

} else {
    res.writeHead(400, {
        'content-type': 'text/plain',
    });
    res.end('Something is wrong. Missing URL.');
    return;
}
}).listen(3000);

对不起我的英语。 谢谢

【问题讨论】:

  • 你能告诉我们你的代码吗?
  • 在这种情况下,查看回调。回调是在进程(如 AJAX 调用)完成后调用的函数。
  • 现在我已经完成了等待 click(SELECTOR, j); console.log("睡眠");睡眠(睡眠); const info = await page.evaluate(() => { ... . 我没有找到所需的回调函数
  • 这是一个糟糕且不可靠的解决方案。你能告诉我们你的代码吗?
  • 请提供更多信息。我有一些问题,什么是 MSEL?什么是 SSEL?网址是什么?模板/index.html 中有什么?你得到什么样的坏数据?为什么你在一个循环内循环?为什么你有一个 sleep() 承诺但不等待那个承诺?当您将信息推送到数据时会发生什么,您是否将其作为响应返回?

标签: node.js ajax google-chrome puppeteer


【解决方案1】:

在回答之前我可以问你很多问题,

  • 什么是 MSEL 和 SSEL?
  • 网址是什么?
  • templates/index.html 中有什么内容?
  • 你得到什么样的坏数据?
  • 为什么要在循环内循环?
  • 为什么你有一个 sleep() 承诺但没有等待这个承诺?
  • 将信息推送到数据时会发生什么,是否将其作为响应返回?

等等等等。列表可以继续,但我们必须从某个地方开始,对吧?我不会编写整个代码,而是为你做所有事情。但我会帮你理解问题。

您的代码中有很多部分丢失,并且由于您没有正确编写内容而出现错误。

我会分开功能。我假设您在某处定义了名为 MSEL、SSEL 的变量。

首先,您没有返回任何响应。这是你需要注意的事情,如果你没有返回响应,那么请求永远不会结束,并导致超时。

http
  .createServer(async (req, res) => {
    if (req.url === "/") {
      if (req.method === "GET") {
        res.writeHead(200, {
          "content-type": "text/html; charset=utf-8",
          "cache-control": "public,max-age=31536000"
        });
        res.end(fs.readFileSync(__dirname + "/templates/index.html"));
        return;
      } else if (req.method === "POST") {
        let body = "";
        await req.on("data", data => (body += data));
        body = qs.parse(body);
        const returnData = await getData({ body, MSEL, SSEL }); // <-- seperate the function
        res.end(returnData); // <-- return the data
      }
    } else {
      res.writeHead(400, {
        "content-type": "text/plain"
      });
      res.end("Something is wrong. Missing URL.");
      return;
    }
  })
  .listen(3000);

这里是单独的函数,注意我是如何在 sleep 之前编写 await 的,并且还稍微重构了一些位和部分,在一切完成后也返回函数。

async function getData({ body, MSEL, SSEL }) {
  let url = body.url;

  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.goto(url);

  let count = selector =>
    page.evaluate(selector => {
      return document.querySelectorAll(selector).length;
    }, selector);

  let sleep = ms => new Promise(resolve => setTimeout(resolve, ms));

  const countM = await count(MSEL),
    countS = await count(SSEL);

  let click = (selector, number) =>
    page.click(`${selector}:nth-child(${number})`);

  let data = [];

  for (let i = 1; i <= countS; i++) {
    await click(SSEL, i);
    await sleep(SLEEP);

    for (let j = 1; j <= countM; j++) {
      await click(MSEL, j);
      await sleep(SLEEP);

      const info = await page.evaluate(() => {
        return {
          val: document.getElementById("val").value,
          cc: document.getElementById("cc").value
        };
      });
      data.push(info);
    }
  }
  return data;
}

我所做的是重构和修复您的代码,但这不是您正在寻找的解决方案,代码甚至可能无法正常工作。

您需要了解 Promise 的工作原理。在复制粘贴我的解决方案之前,请参阅以下教程,希望它会起作用;),

【讨论】:

    猜你喜欢
    • 2020-06-29
    • 1970-01-01
    • 2023-02-03
    • 2020-12-18
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    • 1970-01-01
    • 2022-01-21
    相关资源
    最近更新 更多