在下面的代码中,我希望在继续调用TelegramClient类的所有其他实例方法之前调用实例方法connect.如何通过利用Proxy来实现这一点.到目前为止,还没有调用connect方法.

class TelegramClient {
  async connect() {
    console.log("Connecting to Telegram...");
    // Simulate some asynchronous work
    await new Promise(resolve => setTimeout(resolve, 1000));
    console.log("Connected!");
  }

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

const telegramClient = new TelegramClient();

// Create a Proxy for the Telegram client
const proxiedTelegramClient = new Proxy(telegramClient, {
  async apply(target, thisArg, argumentsList) {
    await target.connect(); // Connect to Telegram before invoking the method
    const result = Reflect.apply(target, thisArg, argumentsList);
    return result;
  },
});

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

预期yields 为...

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

推荐答案

不使用代理的可行方法是使用异步101 100的通用实现.后者可以被视为函数包装的特殊情况.

这样的修饰符接受两个函数proceedhandler以及target对象作为其3个参数.它返回一个异步函数,该函数将再次返回(假定为异步)handler(回调)函数的等待结果.后者确实在(可选的)提供的target的上下文中被调用,同时还被传递给proceed函数、其自己的handler引用和修改后的函数的argumentsarray.

因此,基于这样的修饰符,OP可以通过修改例如如下所示的客户端实例的sendMessage-方法来实现预期的行为.

// client instantiation.
const telegramClient = new TelegramClient;

// client's handler modification.
telegramClient.sendMessage = asyncAround(
  telegramClient.sendMessage,
  ensureConnectedClient,
  telegramClient,
);

...其中ensureConnectedClienthandler函数,它准确地实现了OP正在寻找的东西……

"... [ensure a] connect[ed client] before proceeding with the invocation of every other instance method of the TelegramClient class"

...示例代码...

// implementation of the client specific async `around`-handler.
async function ensureConnectedClient(proceed, handler, args) {
  const client = this;

  // see:
  // - [https://gram.js.org/beta/classes/TelegramClient.html#connected]
  // - [https://gram.js.org/beta/classes/TelegramClient.html#disconnected]

  // ... always ensure a connected client ...

  if (client.disconnected()) {
    console.log('+++ client needs to be reconnected +++');

    await client.connect();
  } else {
    console.log('+++ client is still connected +++');
  }

  // ... before proceeding with any other method.

  return (
    await proceed.apply(client, args)
  );
}

// client instantiation.
const telegramClient = new TelegramClient;

// client's method-modification.
telegramClient.sendMessage = asyncAround(
  telegramClient.sendMessage,
  ensureConnectedClient,
  telegramClient,
);

// client's modified handler invocation.
telegramClient.sendMessage("Hello, Telegram!");
.as-console-wrapper { min-height: 100%!important; top: 0; }
<script>

// client implementation.
class TelegramClient {
  async connect() {
    console.log("Connecting to Telegram...");

    // simulate some asynchronous work.
    await new Promise(resolve => setTimeout(resolve, 1500));

    console.log("Connected!");
  }
  disconnected() {
    // simulate a connect-state method via random boolean.
    return Boolean(Math.floor(Math.random() + 0.5));
  }
  sendMessage(message) {
    console.log(`Sending message: ${ message }`);
  }
}

// implementation of an async `around` modifier.
function asyncAround(proceed, handler, target) {
  return async function (...args) {

    return (
      await handler.call(target ?? null, proceed, handler, args)
    );
  };
}

</script>

Javascript相关问答推荐

Snowflake - .toISOString()错误地舍入JS存储过程中的时间戳

JavaScript .Click()函数不起作用

在卡信息之间切换

如何通过继承contentitable属性的元素捕捉keydown事件?

如何按预期聚合SON数据?

基于变量切换隐藏文本

如何解决chrome—extension代码中的错误,它会实时覆盖google—meet的面部图像?'

如何在Javascript中的控制台上以一行形式打印循环的结果

当作为表达式调用时,如何解析方法decorator 的签名?

如何用拉威尔惯性Vue依赖下拉?

如何将Cookie从服务器发送到用户浏览器

如何强制Sphinx中的自定义js/css文件始终加载更改而不缓存?

如何在每次单击按钮时重新加载HighChart/设置HighChart动画?

使用auth.js保护API路由的Next.JS,FETCH()不起作用

如何在JAVASCRIPT中临时删除eventListener?

在SHINY R中的嵌套模块中,不能使用Java代码

如果没有页面重新加载Angular ,innerHTML属性绑定不会更新

输入的值的类型脚本array.排序()

在渲染turbo流之后滚动到元素

MongoDB中的嵌套搜索