英文:
browser started with puppeteer is not available out of try-catch block
问题
以下是代码部分的翻译:
"use strict";
const puppeteer = require("puppeteer");
(async () => {
try {
const browser = await puppeteer.launch();
console.log(`browser=${browser}`);
var cnt_pages = (await browser.pages()).length;
console.log(`${cnt_pages} pages`);
} catch (error) {
console.error(error);
console.error(`can not launch`);
process.exit();
}
console.log(`browser=${browser}`);
var cnt_pages = (await browser.pages()).length;
console.log(`cnt_pages ${cnt_pages}`);
input("continue?");
})();
根据你提供的代码,我可以看到在try
块中成功启动了浏览器对象browser
,并且在该块内访问它是没有问题的。但是,在try-catch
块之后,当你尝试访问browser
对象时,出现了ReferenceError,表示browser
未定义。这是因为browser
对象的作用域仅限于try
块内,它在try
块之外是不可见的。
所以,你在try-catch
块之后尝试访问browser
对象时,会导致错误,因为该对象在那个作用域中不可用。如果你希望在try-catch
块之后继续使用browser
对象,你需要将其声明在try
块之外,以确保其作用域覆盖整个函数。例如:
"use strict";
const puppeteer = require("puppeteer");
let browser; // 在try块外部声明browser变量
(async () => {
try {
browser = await puppeteer.launch();
console.log(`browser=${browser}`);
var cnt_pages = (await browser.pages()).length;
console.log(`${cnt_pages} pages`);
} catch (error) {
console.error(error);
console.error(`can not launch`);
process.exit();
}
console.log(`browser=${browser}`); // 现在可以在try-catch块之外访问browser对象
var cnt_pages = (await browser.pages()).length;
console.log(`cnt_pages ${cnt_pages}`);
input("continue?");
})();
通过这种方式,你可以在整个函数中访问browser
对象,而不会出现未定义的错误。
英文:
Here is the example code:
"use strict";
const puppeteer = require("puppeteer");
(async () => {
try {
const browser = await puppeteer.launch();
console.log(`browser=${browser}`);
var cnt_pages = (await browser.pages()).length;
console.log(`${cnt_pages} pages`);
} catch (error) {
console.error(error);
console.error(`can not launch`);
process.exit();
}
console.log(`browser=${browser}`);
var cnt_pages = (await browser.pages()).length;
console.log(`cnt_pages ${cnt_pages}`);
input("continue?");
})();
As a result, I get
(node:13408) UnhandledPromiseRejectionWarning: ReferenceError: browser is not defined
at S:\!kyxa\!code\play_chrome_cdp\nodejs_1\!node_tutorial\!play_async\try_catch_browser.js:15:26
at processTicksAndRejections (internal/process/task_queues.js:93:5)
at emitUnhandledRejectionWarning (internal/process/promises.js:168:15)
at processPromiseRejections (internal/process/promises.js:247:11)
at processTicksAndRejections (internal/process/task_queues.js:94:32)
(node:13408) ReferenceError: browser is not defined
at S:\!kyxa\!code\play_chrome_cdp\nodejs_1\!node_tutorial\!play_async\try_catch_browser.js:15:26
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(node:13408) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
at emitDeprecationWarning (internal/process/promises.js:180:11)
at processPromiseRejections (internal/process/promises.js:249:13)
at processTicksAndRejections (internal/process/task_queues.js:94:32)
browser=[object Object]
1 pages
As I see, the browser is available and working in the try
block. But after the try-catch
block it is not available.
Explain me please what happens?
答案1
得分: 1
这是可工作的代码:
"use strict";
const puppeteer = require("puppeteer");
(async () => {
var browser = null;
try {
browser = await puppeteer.launch();
console.log(`browser=${browser}`);
var cnt_pages = (await browser.pages()).length;
console.log(`${cnt_pages} pages`);
} catch (error) {
console.error(error);
console.error(`无法启动`);
process.exit();
}
console.log(`browser=${browser}`);
var cnt_pages = (await browser.pages()).length;
console.log(`cnt_pages ${cnt_pages}`);
})();
英文:
I've explored the issue. I define the browser value in the try but I also use it in the catch. consts are block-scoped, so they are tied to the block. –
This is the working code:
"use strict";
const puppeteer = require("puppeteer");
(async () => {
var browser = null;
try {
browser = await puppeteer.launch();
console.log(`browser=${browser}`);
var cnt_pages = (await browser.pages()).length;
console.log(`${cnt_pages} pages`);
} catch (error) {
console.error(error);
console.error(`can not launch`);
process.exit();
}
console.log(`browser=${browser}`);
var cnt_pages = (await browser.pages()).length;
console.log(`cnt_pages ${cnt_pages}`);
})();
答案2
得分: 0
你可以将 let browser
移出该代码块并移除 const
,但即使在修复了这个作用域问题之后,浏览器资源仍然没有被关闭,而且在 try
/catch
块之后可能发生的任何错误都不会被捕获。以下是我推荐的 Puppeteer 范例代码,用于处理这些情况:
const puppeteer = require("puppeteer");
const scrape = async (page) => {
// 在这里编写你的代码
const url = "https://www.example.com";
await page.goto(url, { waitUntil: "domcontentloaded" });
console.log(await page.title());
};
let browser;
(async () => {
browser = await puppeteer.launch();
const [page] = await browser.pages();
await scrape(page);
})()
.catch((err) => console.error(err))
.finally(() => browser?.close());
英文:
You can elevate let browser
out of the block and remove the const
, but even after fixing this scoping issue, the browser resource still isn't closed, and any errors that might occur after the try
/catch
blocks are uncaught. Here's my preferred Puppeteer boilerplate that handles these situations:
const puppeteer = require("puppeteer");
const scrape = async page => {
// write your code here
const url = "https://www.example.com";
await page.goto(url, {waitUntil: "domcontentloaded"});
console.log(await page.title());
};
let browser;
(async () => {
browser = await puppeteer.launch();
const [page] = await browser.pages();
await scrape(page);
})()
.catch(err => console.error(err))
.finally(() => browser?.close());
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论