Node.js 不可思议的木偶演员行为

Node.js 不可思议的木偶演员行为,node.js,asynchronous,puppeteer,Node.js,Asynchronous,Puppeteer,我使用以下代码: // <-- add event on top of file process.on("unhandledRejection", (reason, p) => { console.error("Unhandled Rejection at: Promise", p, "reason:", reason); // browser.close(); // <-- no need to close the browser here }

我使用以下代码:

// <-- add event on top of file
process.on("unhandledRejection", (reason, p) => {
        console.error("Unhandled Rejection at: Promise", p, "reason:", reason);
        // browser.close(); // <-- no need to close the browser here
});

const puppeteer = require('puppeteer');
async function getPic() {
    try{ // <-- wrap the whole block in try catch
      const browser = await puppeteer.launch(/*{headless: false}*/);
      const page = await browser.newPage();
      await page.setViewport({width: 1000, height: 500}); // <-- add await here so it sets viewport after it creates the page


      //await page.goto('https://www.google.com');  //Old way of doing. It doesn't work for some reason...

      page.goto('https://www.google.com/').catch(error => console.log("error on page.goto()", error));


      // wait for either of events to trigger
      await Promise.race([
        page.waitForNavigation({waitUntil: 'domcontentloaded'}),
        page.waitForNavigation({waitUntil: 'load'})
      ]);


      await page.screenshot({path: 'pic.png'});
      await browser.close(); // <-- close browser after everything is done
    } catch (error) {
      console.log(error);
    }
}

getPic();
然后程序挂起。30秒后,我出现以下错误:

error on page.goto() Error: Navigation T imeout Exceeded: 30000ms exceeded at Promise.then (C:\...\pupet test\node_modules\puppeteer\lib\NavigatorWatcher.js:71:21) at <anonymous>
但我也得到了我要求的照片

1.为什么page.goto失败了,但它仍然得到了图片,这意味着page.goto实际工作了!?
2.我能做些什么来缓解这个奇怪的错误呢?

程序挂起是因为您在没有异步等待或承诺的情况下调用了goto,然后您将它投入到waitForNavigation的竞争中,这使浏览器感到困惑,因为所有三行代码都在后面做同样的事情。它正在尝试导航并等待它

使用异步等待承诺。不要以同步方式调用异步方法。不管怎样,这就是您在示例中必须使用它的方式

await page.goto('https://www.google.com');
如果您想等待页面加载,那么goto函数也包括了这一点。转到后不需要使用waitForNavigation

WaitTill属性还包含domcontentloaded、networkidle2和networkidle0。您可以在文档中阅读更多关于它的详细说明

屏幕截图之所以能正常工作,是因为它是异步执行的,但随后您将等待导航

下面是代码,没有太多的复杂性和承诺

try{ // <-- wrap the whole block in try catch
      const browser = await puppeteer.launch(/*{headless: false}*/);
      const page = await browser.newPage();
      await page.setViewport({width: 1000, height: 500}); // <-- add await here so it sets viewport after it creates the page
      await page.goto('https://www.google.com/', {waitUntil: 'load'})
      await page.screenshot({path: 'pic.png'});
      await browser.close(); // <-- close browser after everything is done
    } catch (error) {
      console.log(error);
    }
下面是它如何在沙箱上完美工作的。


是开始了解这一点的好地方。

的可能副本您不需要异步函数才能使用wait吗?你是怎么做到的?在其他情况下,木偶沙盒会自动为我做到,我只是在顶层添加了它们。很抱歉,您的代码不起作用:错误:超过导航超时:超过承诺的30000ms。然后C:\…\pupet test\node\u modules\puppe eteer\lib\NavigatorWatcher.js:71:21不仅不起作用,而且还无法为我下载图片。我在问题中发布的代码说明了这个错误但至少让我明白了。。。。不管有什么建议,我似乎都无法克服这个错误。人们对这个问题投了反对票,并表示反对,但同时却无法提供任何帮助或理解这是如何发生的。。。。不仅如此,这也是不合逻辑的。为什么会有一个导航超时错误,但它仍然得到图片无论如何?说真的,我太累了,不明白这一点。。。我愿意花钱请人帮我修理这个。。。。
try{ // <-- wrap the whole block in try catch
      const browser = await puppeteer.launch(/*{headless: false}*/);
      const page = await browser.newPage();
      await page.setViewport({width: 1000, height: 500}); // <-- add await here so it sets viewport after it creates the page
      await page.goto('https://www.google.com/', {waitUntil: 'load'})
      await page.screenshot({path: 'pic.png'});
      await browser.close(); // <-- close browser after everything is done
    } catch (error) {
      console.log(error);
    }