【问题标题】:Node.js Return variable from event handler to parent functionNode.js将变量从事件处理程序返回到父函数
【发布时间】:2018-07-01 15:09:49
【问题描述】:

我需要函数scrape 来返回在page.on("request") 事件处理程序中获得的值。

async function scrape(url) {
        const page = await browser.newPage();
        await page.setRequestInterception(true);

        page.on("request", async(request) => {
            return "fish"
        }
        await page.goto(url)
    }

目前:

const ans = await scrape(url)
console.log(ans)
"undefined'

预期:

const ans = await scrape(url)
console.log(ans)
"fish"

【问题讨论】:

  • 你为什么会期待fish? fish 从 page.on 回调中返回,您根本不会在函数抓取中返回任何内容 - 我建议使用 Promise 包裹 page.on ... 例如return new Promise(resolve => { page.on("request", request => { resolve("fish"); }); }); - 不过,这可能是不好的做法,如果页面从不发出“请求”怎么办!
  • 为什么你会这样认为?
  • @JaromandaX 你的建议在我稍微调整后奏效了。感谢您指出这种方法的缺点。我将编写一些代码来处理此类错误情况。再次感谢!
  • after I tweaked it a bit - 真的吗?我的代码出了什么问题:p
  • 哈哈...没错,我只是不得不让 promise 的解析函数异步:return new Promise(async(resolve)... 因为我在其中运行另一个异步函数

标签: javascript node.js puppeteer


【解决方案1】:

当您看到正在等待的事件时,您需要返回已解决的承诺

const matchRequest = request => request.method() === 'GET'; // your filter
async function scrape(url) {
  return new Promise(resolve => {
    const page = await browser.newPage();
    // not sure what your logic is, but if you don't need to cancel or modify requests/resposes you probably don't need interception
    // await page.setRequestInterception(true);
    page.on("response", async(response) => {
        if (matchRequest(response.request())) {
           resolve(response.buffer());
        }
    }
    await page.goto(url);
  })
}

const body = await scrape('https://example.com');

【讨论】:

    【解决方案2】:

    尝试如下:

    async function scrape(url) {
        let sendRequest = []
        const browser = await puppeteer.launch()
        const page = await browser.newPage()
        await page.setRequestInterception(true)
        page.on('request', request => {
          request.continue()
          sendRequest.push('fish')
        })
        await page.goto(url)
        return sendRequest
    }
    

    request.continue() 用于带有可选请求覆盖的继续请求。要使用此功能,应使用page.setRequestInterception 启用请求拦截。如果没有开启请求拦截,立即抛出异常。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-15
      • 1970-01-01
      • 2014-09-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多