You need to enable JavaScript to run this app. 如何向箭头函数传参?Puppeteer $$eval回调selector未定义报错
优惠活动
大模型
产品
解决方案
定价
更多

如何向箭头函数传参?Puppeteer $$eval回调selector未定义报错

问题根因

page.$$eval的执行逻辑是:将传入的回调函数序列化为字符串,直接注入到浏览器的页面上下文中运行,整个执行过程和Node.js运行环境完全隔离,回调内部无法通过闭包访问Node.js侧作用域的任何变量。
你代码中引用的selector、contractsPo都是Node.js侧定义的变量,从来没有被传入浏览器的执行环境,所以执行到if判断语句时,就会抛出ReferenceError: selector is not defined的错误。

修复方案

page.$$eval支持可变额外传参:从函数的第三个入参开始,所有传入的值都会被序列化后透传到浏览器的回调执行上下文,作为回调的形参按顺序接收。只需要把回调内部要用到的外部值,全部通过这个渠道传入即可解决问题。

修正后的代码实现

static async valuesToArray(selector: string): Promise<void> {
  // 提前取出需要在页面回调中使用的具体常量值
  const dateColSelector = contractsPo.contractDateCol;
  
  const data: (string | Date)[] = await page.$$eval(
    selector,
    // 回调的形参顺序,和透传的参数顺序一一对应
    (cells, currentSelector, targetDateSelector) => {
      return cells.map(cell => {
        if (currentSelector === targetDateSelector) {
          return new Date(
            cell.textContent!.replace(/(\d{2}).(\d{2}).(\d{4})/, '$2/$1/$3'),
          );
        } else {
          return cell.textContent!;
        }
      });
    },
    // 以下为需要透传到浏览器执行环境的参数
    selector,
    dateColSelector
  );
}
注意事项
  • 回调运行在浏览器的独立执行环境,不能依赖Node.js的闭包机制读取外部变量,所有回调内部要用到的外部值,必须通过$$eval的额外参数显式传递。
  • 透传的参数必须是支持结构化克隆的纯数据,比如字符串、数字、普通对象、数组,不能传Node.js侧的函数、类实例、带自定义方法的对象,否则会在序列化阶段直接报错。
  • 如果用到的选择器是固定常量,也可以直接把值硬编码在回调内部,省去不必要的参数透传步骤。

内容的提问来源于stack exchange,提问作者Vladimir Krygin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.27 03:27:03