在 Node 中循环查询结果,但我总是丢失循环?

Looping over query results in Node, but I keep losing my loop?

背景知识:我正在构建一个工具,可以按计划截取网页的屏幕截图。它还存储了有关如何截取屏幕截图的设置(例如,隐藏某些页面元素,在长轮询请求或具有动画的启动页面的情况下等待 X 秒)

所以很自然地,我必须从数据库中读取这些东西,并将这些结果循环到基于这些变量的 运行 代码块中。

我可以很好地输出我的记录。我可以单独遍历它们就好了。但是当我尝试即插即用到现有的代码块中时,事情就崩溃了。不知何故,这打破了我的循环,页面下方的代码无法识别我的数据库循环中的变量。

假设我的数据库记录被分配给变量 poo 并且我对我之前的语法有信心:

for (var i = 0; i < poo.length; i++) {
    console.log('The name of this task is ' + poo[i].PrettyName); 

    //So far so good! I can output my column names as variables and do what I want with them.

    Screenshot(poo[i].URL);  
    //This works too!

    async function Screenshot(url) {
    const browser = await puppeteer.launch({
   headless: true,
   defaultViewport: {width: 1920, height: 1080},
   args: [
   "--no-sandbox",
   "--disable-gpu",
   ]
 });

//This is not the end of my code, but basically nothing after this point works. 
//When I try to read or log any variable, 
//even ones that worked before, it tells me "cannot read property ___ of undefined."

我是不是不小心在某处用括号打断了循环?这是异步函数魔法吗?误解我什么时候必须应用回调?

即使我在异步函数 运行s 之前手动输入 10 秒的延迟,变量在这一点之后仍然被破坏,这应该有足够的时间来形成一个记录集进行处理。

作为参考,您看到的代码的内容是 puppeteer 模块。

我认为您在代码中犯了一个小错误:

for (var i = 0; i < poo.length; i++) {
    console.log('The name of this task is ' + poo[i].PrettyName); 

    //So far so good! I can output my column names as variables and do what I want with them.

    Screenshot(poo[i].URL);  
    //This works too!

    async function Screenshot(url) {
    const browser = await puppeteer.launch({
   headless: true,
   defaultViewport: {width: 1920, height: 1080},
   args: [
   "--no-sandbox",
   "--disable-gpu",
   ]
 });
//^

您可能不小心将 ); 放在了循环的末尾。

我和你有同样的问题。我在每个 mq 任务中调用屏幕截图功能。所以当有很多任务同时执行时,它会创建很多Chromium进程。我的功能在这里:

module.exports = async (_browser, sheetJson) => {
    const browser = await puppeteer.launch({args: ['--no-sandbox']});
    const page = await browser.newPage();
    //goto.page
    const thumbnailPath = path.join('test/out', shortId() + '.png');
    await page.screenshot({
        path: thumbnailPath,
        fullPage: true,
    });
    await page.close();
    await browser.close();
    return thumbnailPath;
}

我认为 Chromium 进程太多导致内存泄漏。因为每个 mq 任务都会创建一个浏览器 instance.So 我尝试创建一个 glob 浏览器实例。而且我认为它有效,只有大约五个 Chromium 进程。

确实基于当前共享的示例,您的怀疑是正确的:您错过了两个的右括号:(1) Screenshot() 函数和 (2) for 循环。

修复它们的示例:

const poo = [
  { PrettyName: 'one', URL: 'https://google.com' },
  { PrettyName: 'two', URL: 'https://google.fr' }
];

for (var i = 0; i < poo.length; i++) {
  console.log('The name of this task is ' + poo[i].PrettyName);
  Screenshot(poo[i].URL);

  async function Screenshot(url) {
    const browser = await puppeteer.launch({
      headless: true,
      defaultViewport: { width: 1920, height: 1080 },
      args: ['--no-sandbox', '--disable-gpu']
    });
     // puppeteer methods goes here
  } // ⚠️ closes Screenshot()
}  // ⚠️ closes for loop

console.log('Loop ended succesfully');

按预期运行。

输出:

The name of this task is one
The name of this task is two
Loop ended succesfully

注意: 当然,代码中可能还有其他大括号问题,但需要在 minimal, reproducible example 中使用更大的代码部分才能说明。

在我的 Google 旅程中找到 a solution,感谢 Reddit 用户 kranker。

In any closures created in the loop, let variables will be bound to the value from only that iteration of the loop, whereas var variables will be the current value of the variable.

必须将 var 更改为 let

for (let i = 0; i < poo.length; i++)

现在我的变量在页面中一直正确保留,我的脚本可以同时处理多个事情。