【问题标题】:js doesnt wait until the promise is fullfilled [duplicate]js不会等到承诺完成[重复]
【发布时间】:2021-05-12 07:04:40
【问题描述】:

我正试图在 puppeteer 的帮助下从网站获取一些链接。

async function getLinks(){

    
    const first = 'first';
    const last = 'last';

    const browser = await browserControl.startBrowser();
    const page = await browser.newPage();

    await page.goto(url_baseStats);
    // await page.waitForNavigation();

    let links = await page.evaluate((first, last) => {
        try {
            let links = Array.from(document.querySelectorAll('a'), a => a.getAttribute('href'));
            links = links.slice(links.indexOf(first), links.indexOf(last));
            return links;
        } catch(err) {
            throw err;
        }
    });
    
    console.log("links:", links);
    return links;
    
}

我有两个问题:

  1. 当我运行调试器时,他会到达“await page.evaluate((...”-point,然后跳转 直接到“console.log(...”。他为什么不等?

  2. 为什么我需要将变量 first 和 last 作为参数传递给评估函数? 我上面定义的,应该在评估函数的范围内吧?!?

提前致谢 ;_)

【问题讨论】:

  • 是时候进行更多的调试了:让你的函数在你的catch之后返回一个值,这样你就可以检查它是否真的立即出错了。至于为什么需要先和最后传递:you don't,除非您希望“不在浏览器中运行”上下文中的值传递到浏览器上下文中,否则您可以这样做。在这种情况下,您似乎忘记设置 evaluate(..., first, last) 以便将这两个值放入您的函数中。
  • 显然(根据文档)page.evaluate() 仅在函数回调返回 Promise 时才等待。 (但是文档不是很清楚。)
  • 我不知道为什么firstlast也在那里; .evaluate() 回调的参数应该在 .evaluate() 调用本身的回调函数之后传递。他们为什么在那里?你期望他们有什么价值观? 编辑哦等等;是的,将参数first, last 从回调函数中取出。实际上,它们将是 undefined,因此回调不会像您预期的那样工作。
  • 那么您必须将firstlast 作为第二个和第三个参数传递给.evaluate() 调用。 (并将参数放回去。)
  • 函数作为文本从Node域传输到浏览器域,所以正常的范围规则没有意义。

标签: javascript node.js async-await puppeteer


【解决方案1】:

仅供以后的观众看,cmets的总结:

在 page.evaluate() 函数中运行的所有内容都是在浏览器页面的上下文中完成的。该脚本在浏览器中运行,而不是在 node.js 中。因此,一些常用的 js 规则在这里无效。 例如:

  1. 如果您记录任何内容,它将显示在浏览器控制台中,如果您以无头方式运行,您将看不到。
  2. 你也不能在函数内部设置节点断点
  3. 通常范围无效,您需要传递参数

;_)

【讨论】:

    猜你喜欢
    • 2018-07-21
    • 1970-01-01
    • 2020-11-20
    • 2017-06-17
    • 2016-06-17
    • 2022-01-12
    • 2018-03-05
    • 1970-01-01
    • 2019-05-29
    相关资源
    最近更新 更多