google-cloud-functions - Puppeteer Google Cloud Function Pub/Sub Trigger 无法打开浏览器
问题描述
我正在尝试在 GCP 中创建一个可以由 Pub/Sub 消息触发的 Puppeteer 函数。该函数是可调用的,但不会像预期的那样运行,并且一旦浏览器尝试初始化就会引发超时错误。触发器是否可能使用与 HTTP 触发器不同的 NodeJS 环境?
我对 NodeJS 也很陌生,所以如果问题非常明显,我提前道歉。
我为按预期运行的函数创建了一个 HTTP 触发器。在创建云函数时,我将下面的 Puppeteer 函数复制/粘贴到 index.js 中,但为了清楚起见,在示例中分开了两个触发器正在运行相同的函数。
木偶功能
const puppeteer = require('puppeteer');
scrapeUglyWebsite = () => {
return new Promise(async(resolve, reject) => {
await puppeteer.launch({
headless: true,
args: ['--no-sandbox']
})
.then(async (browser) => {
const page = await browser.newPage();
await page.goto('http://suzannecollinsbooks.com/', {waitUntil: 'load', timeout: 0})
.then(async () => {
//Wait for content to load
await page.waitForFunction('document.body !== null && document.body.innerText.includes(\'Jon Scieszka\')');
//Evaluate page contents
const dom_eval = await page.evaluate(() => document.body.innerText.includes("Here’s a picture of me with a rat"));
await browser.close();
resolve(dom_eval);
});
}).catch((err) => {
reject(err);
});
});
};
HTTP 触发器 - index.js
exports.cloudFunctionTest = (req, res) => {
scrapeUglyWebsite()
.then((results) => {
if(results) {
res.send('Suzanne Collins takes pictures with rats.');
} else {
res.send("Suzzane Collins doesn't take pictures with rats.");
};
})
.catch((err) => {
res.send(err.toString());
});
发布/订阅触发器 - index.js
exports.cloudFunctionTest = (data, context) => {
scrapeUglyWebsite()
.then((results) => {
if(results) {
console.log('Suzanne Collins takes pictures with rats.');
} else {
console.log("Suzzane Collins doesn't take pictures with rats.");
};
})
.catch((err) => {
console.log(err.toString());
});
};
包.json
{
"name": "test",
"version": "0.0.1",
"engines": {
"node": "8"
},
"dependencies": {
"puppeteer": "^1.6.0"
}
}
HTTP 触发器的行为与预期结果正确
Suzanne Collins takes pictures with rats.
Pub/Sub 触发器抛出以下错误,没有输出
TimeoutError: Timed out after 30000 ms while trying to connect to Chrome! The only Chrome revision guaranteed to work is r662092
解决方案
我知道这已经晚了,但发生 TimeoutError 的原因是云功能不会自动等待异步任务完成。所以 in exports.cloudFunctionTest
,scrapeUglyWebsite()
被调用但函数不等待承诺被履行,所以程序终止。因此错误
有关后台功能如何在 NodeJs 中工作的更多信息
为了让函数等待scrapeUglyWebsite()
,您需要返回一个完成的承诺,scrapeUglyWebsite()
并且结果代码完成。
就个人而言,我通过简单地将当前在我正在导出的函数中的代码包装在另一个异步函数中然后返回包装函数的承诺来让它工作。
async function wrapper() {
try {
const result = await scrapeUglyWebsite();
if(results) {
console.log('Suzanne Collins takes pictures with rats.');
} else {
console.log("Suzzane Collins doesn't take pictures with rats.");
};
} catch (err) {
console.log(err.toString());
}
}
然后在要导出的函数中:
exports.cloudFunctionTest = (data, context) => {
return wrapper();
};
推荐阅读
- html - 提交表单后如何指定 URL?
- php - 带有图形的按钮功能
- javascript - 如何使用 Jest 从 axios-hooks 模拟 useAxios 钩子?(错误:未捕获 [TypeError: undefined is not a function])
- python - h2o deep_copy 强制 Java 堆空间错误
- php - Laravel - 避免重复预订时间段
- java - 有没有办法递归调用 findMatch ?
- ios - 为什么标签栏图标未显示在我的栏项目图像中?
- facebook-graph-api - 可以从外部链接上传可播放广告吗?
- css - 绝对面板中的滚动条覆盖(并使其处于非活动状态)操作按钮
- angular - Angular 8 - 如何在桌面和移动设备上触发具有不同值的动画?