You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Proxy在执行其他方法前自动调用connect方法?

如何用Proxy实现调用TelegramClient实例方法前自动执行connect?

我希望调用TelegramClient类的所有其他实例方法前,先自动执行connect方法,但目前的Proxy代码里connect并未被调用。

原代码如下:

class TelegramClient {
  async connect() {
    console.log("Connecting to Telegram...");
    // 模拟异步操作
    await new Promise(resolve => setTimeout(resolve, 1000));
    console.log("Connected!");
  }

  sendMessage(message: string) {
    console.log(`Sending message: ${message}`);
  }
}

const telegramClient = new TelegramClient();

// 创建Telegram客户端的Proxy
const proxiedTelegramClient = new Proxy(telegramClient, {
  async apply(target, thisArg, argumentsList) {
    await target.connect(); // 调用方法前先连接Telegram
    const result = Reflect.apply(target, thisArg, argumentsList);
    return result;
  },
});

proxiedTelegramClient.sendMessage("Hello, Telegram!");

预期输出:

Connecting to Telegram...
Connected!
Sending message: Hello, Telegram!

问题原因

你用的apply陷阱只负责拦截函数的直接调用(比如proxy()这种形式),而调用对象的方法(proxy.sendMessage())分为两步:首先通过get操作获取sendMessage属性,然后才会执行这个函数。所以你的apply陷阱根本没被触发,自然不会调用connect。

解决方案:使用get陷阱拦截方法访问

我们需要在get陷阱里拦截方法属性的访问,返回一个包装函数,先执行connect(可以加个标记避免重复连接),再执行原方法。

修改后的代码:

class TelegramClient {
  private _isConnected = false; // 标记是否已连接

  async connect() {
    if (this._isConnected) return; // 避免重复连接
    console.log("Connecting to Telegram...");
    await new Promise(resolve => setTimeout(resolve, 1000));
    console.log("Connected!");
    this._isConnected = true;
  }

  sendMessage(message: string) {
    console.log(`Sending message: ${message}`);
  }
}

const telegramClient = new TelegramClient();

const proxiedTelegramClient = new Proxy(telegramClient, {
  get(target, prop) {
    const originalProp = Reflect.get(target, prop);
    
    // 如果访问的是方法,且不是connect本身
    if (typeof originalProp === 'function' && prop !== 'connect') {
      // 返回包装后的异步函数
      return async function(...args) {
        await target.connect(); // 先执行连接
        // 绑定原方法的this,再调用
        return originalProp.apply(target, args);
      }
    }
    
    return originalProp;
  }
});

// 测试调用
proxiedTelegramClient.sendMessage("Hello, Telegram!");
// 第二次调用不会重复连接
proxiedTelegramClient.sendMessage("Second message!");

关键点说明

  1. 添加连接状态标记:给TelegramClient加_isConnected属性,避免每次调用方法都重复执行connect,符合实际场景(连接只需要一次)。
  2. get陷阱拦截方法:当访问的属性是函数且不是connect时,返回一个包装函数,先执行connect再调用原方法。
  3. 绑定this上下文:用apply确保原方法执行时this指向原始实例,避免上下文丢失。

执行后输出符合预期:

Connecting to Telegram...
Connected!
Sending message: Hello, Telegram!
Sending message: Second message!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 18:03:25