无法导出从人偶浏览器创建的 wsEndpoint
Can't export wsEndpoint created from puppeteer browser
我试图在启动时打开一个 puppeteer 浏览器,然后导出 wsEndpoint,这样我就可以使用 link 连接到浏览器,而不是每次调用该函数时都打开一个新浏览器。
这是文件 app.js
中的代码片段,它是节点的入口点。
const mainFunction = async () => {
const browser = await puppeteer.launch()
const wsEndpoint = browser.wsEndpoint()
return wsEndpoint
}
mainFunction().then(async endpoint => {
console.log(endpoint)
module.exports = endpoint
})
启动后,控制台日志 returns a link 然后我导出
这是实用程序文件中的代码片段 equities.js
const puppeteer = require("puppeteer")
const endpoint = require("../../app.js")
module.exports = async(symbol)=>{
console.log(endpoint)
const browser = await puppeteer.connect({connectWSEndpoint: endpoint})
}
每次调用该函数时,控制台仅记录 returns 一个空对象,这意味着 app.js
中的导出由于某种原因失败。我尝试 google 一些东西并尝试了不同的导出方式,但 none 似乎有效。有人可以帮助指导我吗?非常感谢您。
我觉得这里有些地方不对劲——这段代码感觉好像没有经过测试,导致了多点故障。尝试采取更小的步骤,这样您就可以隔离问题而不是累积问题。
首先,mainFunction
代码放弃了 browser
对象,创建了无法关闭的泄漏子进程资源。
我会 return 或将 browser
变量与端点一起存储,以便有人可以通过函数清理它。或者只是 return browser
并让客户端代码根据需要将端点从中拉出,以及管理和关闭资源。
接下来导出代码:
mainFunction().then(async endpoint => {
console.log(endpoint)
module.exports = endpoint
})
我不明白这个额外的 then
包装器接收一个从未使用 await
的 async
解析函数的动机。您可能认为节点 await
包含所有这些代码,然后在客户端文件的 require
同步运行之前设置 module.exports
值。那就是not the case,可以用一段更简单的代码来确定:
app.js(为方便起见,在整个 post 的同一文件夹中):
const mainFunction = async () => 42;
mainFunction().then(async endpoint => {
console.log("endpoint":, endpoint)
module.exports = endpoint
})
index.js:
const endpoint = require("./app");
console.log("imported:", endpoint);
node index
给我:
imported: {}
endpoint: 42
承诺在 require
之后解决,它同步引入了默认的空白对象 module.exports
-- 可能不是您所期望的。
如果你有异步代码,它必须永远保持异步,包括导出和导入。尝试直接导出承诺,然后 await
在客户端中执行它:
app.js:
const mainFunction = async () => 42;
module.exports = mainFunction;
index.js:
const getEndpoint = require("./app");
getEndpoint().then(endpoint => console.log("imported:", endpoint));
运行ning node index
给我:imported: 42
.
equities.js
中的客户端代码看起来更合理,因为它同步导出一个 promise,但它必须 await
endpoint
promise 它在任何使用它的地方导入。
此外,Puppeteer 在 puppeteer.connect({connectWSEndpoint: endpoint})
、Error: Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect
上抛出。我会把它留给你根据你的目标来解决。
这是修复承诺问题的重写草图,但这只是一个概念证明,需要进行调整才能完成您想要做的任何事情:
app.js:
const puppeteer = require("puppeteer");
const browserPromise = puppeteer.launch();
const endpointPromise = browserPromise
.then(browser => browser.wsEndpoint())
;
module.exports = {browserPromise, endpointPromise};
equities.js:
const puppeteer = require("puppeteer");
const {browserPromise, endpointPromise} = require("./app");
module.exports = async symbol => {
const endpoint = await endpointPromise;
console.log(endpoint);
//const browser = await puppeteer.connect({connectWSEndpoint: endpoint}) // FIXME
const browser = await browserPromise;
await browser.close();
};
index.js:
const equitiesFn = require("./equities");
(async () => {
await equitiesFn();
})();
运行 node index
你应该会看到打印的 ws。
请注意,如果需要,您可以将导出的承诺包装在函数中或作为对象的一部分,对象是库接口更典型的抽象层。但这并没有改变基本的异步性。客户端将调用导出的函数并等待端点 and/or 浏览器承诺通过额外的间接层,
require("./app").getBrowser().then(browser => /* */);
对比
require("./app").browserPromise.then(browser => /* */);
如果您不想公开浏览器对象,那很好,但我建议公开一个关闭底层浏览器的函数,这样您就可以干净地退出,例如
app.js:
const puppeteer = require("puppeteer");
const browserPromise = puppeteer.launch();
const closeBrowser = () =>
browserPromise.then(browser => browser.close())
;
module.exports = {closeBrowser};
index.js:
require("./app")
.closeBrowser()
.then(() => console.log("closed"))
;
我试图在启动时打开一个 puppeteer 浏览器,然后导出 wsEndpoint,这样我就可以使用 link 连接到浏览器,而不是每次调用该函数时都打开一个新浏览器。
这是文件 app.js
中的代码片段,它是节点的入口点。
const mainFunction = async () => {
const browser = await puppeteer.launch()
const wsEndpoint = browser.wsEndpoint()
return wsEndpoint
}
mainFunction().then(async endpoint => {
console.log(endpoint)
module.exports = endpoint
})
启动后,控制台日志 returns a link 然后我导出
这是实用程序文件中的代码片段 equities.js
const puppeteer = require("puppeteer")
const endpoint = require("../../app.js")
module.exports = async(symbol)=>{
console.log(endpoint)
const browser = await puppeteer.connect({connectWSEndpoint: endpoint})
}
每次调用该函数时,控制台仅记录 returns 一个空对象,这意味着 app.js
中的导出由于某种原因失败。我尝试 google 一些东西并尝试了不同的导出方式,但 none 似乎有效。有人可以帮助指导我吗?非常感谢您。
我觉得这里有些地方不对劲——这段代码感觉好像没有经过测试,导致了多点故障。尝试采取更小的步骤,这样您就可以隔离问题而不是累积问题。
首先,mainFunction
代码放弃了 browser
对象,创建了无法关闭的泄漏子进程资源。
我会 return 或将 browser
变量与端点一起存储,以便有人可以通过函数清理它。或者只是 return browser
并让客户端代码根据需要将端点从中拉出,以及管理和关闭资源。
接下来导出代码:
mainFunction().then(async endpoint => {
console.log(endpoint)
module.exports = endpoint
})
我不明白这个额外的 then
包装器接收一个从未使用 await
的 async
解析函数的动机。您可能认为节点 await
包含所有这些代码,然后在客户端文件的 require
同步运行之前设置 module.exports
值。那就是not the case,可以用一段更简单的代码来确定:
app.js(为方便起见,在整个 post 的同一文件夹中):
const mainFunction = async () => 42;
mainFunction().then(async endpoint => {
console.log("endpoint":, endpoint)
module.exports = endpoint
})
index.js:
const endpoint = require("./app");
console.log("imported:", endpoint);
node index
给我:
imported: {}
endpoint: 42
承诺在 require
之后解决,它同步引入了默认的空白对象 module.exports
-- 可能不是您所期望的。
如果你有异步代码,它必须永远保持异步,包括导出和导入。尝试直接导出承诺,然后 await
在客户端中执行它:
app.js:
const mainFunction = async () => 42;
module.exports = mainFunction;
index.js:
const getEndpoint = require("./app");
getEndpoint().then(endpoint => console.log("imported:", endpoint));
运行ning node index
给我:imported: 42
.
equities.js
中的客户端代码看起来更合理,因为它同步导出一个 promise,但它必须 await
endpoint
promise 它在任何使用它的地方导入。
此外,Puppeteer 在 puppeteer.connect({connectWSEndpoint: endpoint})
、Error: Exactly one of browserWSEndpoint, browserURL or transport must be passed to puppeteer.connect
上抛出。我会把它留给你根据你的目标来解决。
这是修复承诺问题的重写草图,但这只是一个概念证明,需要进行调整才能完成您想要做的任何事情:
app.js:
const puppeteer = require("puppeteer");
const browserPromise = puppeteer.launch();
const endpointPromise = browserPromise
.then(browser => browser.wsEndpoint())
;
module.exports = {browserPromise, endpointPromise};
equities.js:
const puppeteer = require("puppeteer");
const {browserPromise, endpointPromise} = require("./app");
module.exports = async symbol => {
const endpoint = await endpointPromise;
console.log(endpoint);
//const browser = await puppeteer.connect({connectWSEndpoint: endpoint}) // FIXME
const browser = await browserPromise;
await browser.close();
};
index.js:
const equitiesFn = require("./equities");
(async () => {
await equitiesFn();
})();
运行 node index
你应该会看到打印的 ws。
请注意,如果需要,您可以将导出的承诺包装在函数中或作为对象的一部分,对象是库接口更典型的抽象层。但这并没有改变基本的异步性。客户端将调用导出的函数并等待端点 and/or 浏览器承诺通过额外的间接层,
require("./app").getBrowser().then(browser => /* */);
对比
require("./app").browserPromise.then(browser => /* */);
如果您不想公开浏览器对象,那很好,但我建议公开一个关闭底层浏览器的函数,这样您就可以干净地退出,例如
app.js:
const puppeteer = require("puppeteer");
const browserPromise = puppeteer.launch();
const closeBrowser = () =>
browserPromise.then(browser => browser.close())
;
module.exports = {closeBrowser};
index.js:
require("./app")
.closeBrowser()
.then(() => console.log("closed"))
;