【问题标题】:Puppeteer Google Cloud Function Pub/Sub Trigger can't open browserPuppeteer Google Cloud Function Pub/Sub Trigger 无法打开浏览器
【发布时间】:2019-06-13 12:49:32
【问题描述】:

我正在尝试在 GCP 中创建一个可以由 Pub/Sub 消息触发的 Puppeteer 函数。该函数是可调用的,但不会像预期的那样运行,并且一旦浏览器尝试初始化就会引发超时错误。触发器是否可能使用与 HTTP 触发器不同的 NodeJS 环境?

我对 NodeJS 也很陌生,所以如果问题很明显,我提前道歉。

我已经为按预期运行的函数创建了一个 HTTP 触发器。在创建 Cloud Function 时,我将下面的 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());
        });
};

package.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

【问题讨论】:

    标签: google-cloud-functions puppeteer google-cloud-pubsub


    【解决方案1】:

    我知道这已经晚了,但发生 TimeoutError 的原因是云函数不会自动等待异步任务完成。所以在exports.cloudFunctionTest 中,scrapeUglyWebsite() 被调用了,但是函数并没有等待 promise 被实现,所以程序终止了。因此错误

    更多信息 here 关于后台函数如何在 NodeJs 中工作

    为了让函数等待scrapeUglyWebsite(),您需要返回一个在scrapeUglyWebsite() 和结果代码完成时完成的promise。

    就我个人而言,我只需将当前在我正在导出的函数中的代码包装在另一个异步函数中,然后返回包装函数的承诺,就可以让它工作。

    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();
    };
    

    【讨论】:

      猜你喜欢
      • 2022-12-28
      • 1970-01-01
      • 2021-02-21
      • 2022-01-13
      • 1970-01-01
      • 2019-08-18
      • 2015-05-19
      • 2021-12-12
      • 1970-01-01
      相关资源
      最近更新 更多