如何为事件处理程序编写中间件复用客户端可用性校验逻辑?
太懂这种重复代码的痛苦了!每次写事件处理都要先搞一遍客户端检查,不仅冗余还容易漏改。用中间件抽离这个公共逻辑绝对是最优解,我来给你捋捋具体怎么实现:
核心思路
我们可以把「获取可用客户端+可用性校验」这个横切逻辑封装成一个中间件包装函数,它会先帮你完成这些前置操作,只有当客户端可用时,才会把请求转发给真正的业务处理函数;如果客户端不可用,直接返回预设的错误提示。这样业务代码就能彻底摆脱重复逻辑,只专注自己的业务逻辑。
具体实现步骤
1. 编写中间件生成函数
先写一个通用的中间件工厂函数,它接收你的业务处理函数作为参数,返回一个包装后的新函数,负责处理客户端的获取和校验:
private createClientMiddleware( handler: (msg: RpcConsumerMessage, client: RequestClient) => Promise<any> ) { return async (msg: RpcConsumerMessage) => { // 公共逻辑:获取客户端 const client = this.getClient(msg); // 公共校验:客户端不可用直接返回错误 if (!client) { return "Service unavailable"; // 这里也可以根据你的RPC协议返回结构化错误,比如 { code: 503, message: "Service unavailable" } } // 客户端可用时,调用真正的业务处理函数,并传递客户端实例 return handler(msg, client); }; }
2. 简化业务处理函数
现在你的事件处理函数可以完全去掉重复的客户端逻辑,直接接收已经校验过的客户端,专注写业务:
// 处理requestA的业务逻辑,直接拿到可用的client private onRequestA = async (msg: RpcConsumerMessage, client: RequestClient) => { // 这里写你的业务代码,比如调用客户端的方法 const result = await client.processRequestA(msg.data); return result; }; // 同理,处理requestB的逻辑也一样简洁 private onRequestB = async (msg: RpcConsumerMessage, client: RequestClient) => { return await client.processRequestB(msg.data); };
3. 用中间件包装后注册事件
最后在构造函数里注册事件时,用我们的中间件把业务处理函数包一下就行:
public constructor(consumer: RpcConsumer) { consumer.on('requestA', this.createClientMiddleware(this.onRequestA)); consumer.on('requestB', this.createClientMiddleware(this.onRequestB)); }
额外扩展
如果以后需要加其他公共逻辑(比如日志记录、参数校验),还可以用中间件链式调用的方式,比如再写一个日志中间件,然后把多个中间件组合起来:
// 日志中间件示例 private createLoggingMiddleware(handler: (msg: RpcConsumerMessage, client: RequestClient) => Promise<any>) { return async (msg: RpcConsumerMessage, client: RequestClient) => { console.log(`Processing ${msg.type} request`); const result = await handler(msg, client); console.log(`Completed ${msg.type} request`); return result; }; } // 组合中间件 consumer.on( 'requestA', this.createClientMiddleware(this.createLoggingMiddleware(this.onRequestA)) );
这样的架构不仅让代码更干净,还大大提升了可维护性——以后修改公共逻辑只需要改对应的中间件,不用逐个修改事件处理函数!
内容的提问来源于stack exchange,提问作者kentor
相关产品推荐
相关产品推荐

