Javascript 对于在异步操作中未定义循环变量的类型

Javascript 对于在异步操作中未定义循环变量的类型,javascript,async-await,puppeteer,Javascript,Async Await,Puppeteer,我想将数组中的数字按顺序写入HTML输入。my for..of循环中的数组值仅在异步操作中返回未定义的值。这是我的密码: const puppeteer = require('puppeteer'); const years = [2000,2001,2002]; (async () => { const browser = await puppeteer.launch({ executablePath: './chromium/chrome.exe',

我想将数组中的数字按顺序写入HTML输入。my for..of循环中的数组值仅在异步操作中返回未定义的值。这是我的密码:

const puppeteer = require('puppeteer');
const years = [2000,2001,2002];

(async () => {
    const browser = await puppeteer.launch({
        executablePath: './chromium/chrome.exe',
        headless:false,
        product:'chrome',
        userDataDir: './cache'
    });
    const page = (await browser.pages())[0];
    await page.setViewport({width:1920, height:1080});
    await page.goto("https://www.immotop.lu/search/");

    const example = async ()=>  {
        for (year of years){
            await page.$eval('#search_form > div.filt-but-block > button.button-l3.filter-pan', el => el.click());
            await page.$eval('#year_build', el => el.value = "" + year) // year is undefined here
        }
    }
    example().then(() =>{
        console.log('done');
    })
})();
我认为这是由于在使用wait执行异步代码时通过数组进行同步循环,因此循环完成,变量在wait执行之前消失。此外,我听说应该有一种方法将变量单独保存在函数体中,但到目前为止,我还没有弄明白如何做

以下是错误消息:

(node:23492) UnhandledPromiseRejectionWarning: Error: Evaluation failed: 
ReferenceError: year is not defined
 (node:23492) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
    (node:23492) [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.

您尚未在for..of循环中定义迭代器变量,只需使用let关键字在for..of循环中定义“year”

这引发错误的原因可能是因为您可能正在将“Strict Mode”与“use Strict;”一起使用在.js文件的最顶端。因为在严格模式下,全局变量会为..in或for..类循环抛出异常

  for (let year of years){
                await page.$eval('#search_form > div.filt-but-block > button.button-l3.filter-pan', el => el.click());
                await page.$eval('#year_build', el => el.value = "" + year) // year is undefined here
                });
            }

当我们使用Puppeter时,有两个单独的javascript上下文:

  • 节点上下文,脚本从中运行
  • 浏览器上下文:在Chromium-Puppeter中工作的完全不同的javascript运行时只发送函数并接收它们的计算结果
  • 浏览器中不存在在节点上下文中声明的变量和函数,反之亦然

    // NODE CONTEXT
    // this script works in Node.js
    const puppeteer = require('puppeteer');
    const years = [2000,2001,2002];
    
    (async () => {
        const browser = await puppeteer.launch();
        const page = (await browser.pages())[0];
        await page.goto("https://www.immotop.lu/search/");
    
        for (year of years) { // <-- year exists in node.js context
            // But all functions executed inside of evaluation methods,
            // like page.evaluate, page.$eval, page.$$eval
            // are actually run in the browser
            // and there is no "year" variable there
            await page.$eval('#search_form > div.filt-but-block > button.button-l3.filter-pan', el => el.click());
            await page.$eval('#year_build', el => el.value = "" + year) // year is undefined here
        }
    })();
    
    args
    就是我们要找的。这意味着在执行函数之后,我们可以根据需要传递尽可能多的附加参数。更正后的代码如下所示:

    for (year of years) {
      const yearBuild = await page.$eval(
        "#year_build", // <-- element selector
        (el, yearFromNode) => (el.value = "" + yearFromNode), // function to run
        year // <-- variable from node context to send to the browser
      );
    }
    
    for(年份){
    const yearBuild=等待页面$eval(
    “#year_build”,//(el.value=”“+yearFromNode),//要运行的函数
    
    year//您错过了循环中的变量定义yiu必须在year之前使用let谢谢,确实修复了,但仍然存在相同的错误。谢谢,我现在使用了'let',它仍然抛出相同的异常。据我所知,我没有使用严格模式,const puppeter=require('puppeter'));是我的原始代码中唯一缺少的一行。非常感谢!我现在非常理解这个问题。
    for (year of years) {
      const yearBuild = await page.$eval(
        "#year_build", // <-- element selector
        (el, yearFromNode) => (el.value = "" + yearFromNode), // function to run
        year // <-- variable from node context to send to the browser
      );
    }