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

JavaScript中两个异步方法的代码复用最优方案问询

嘿,看起来你有两个功能相近的异步查询方法,想要优化代码复用对吧?我来给你分享一个在TypeScript结合Knex场景下的最优复用方案——提取通用查询构建逻辑,让代码更简洁、易维护。

核心思路

两个方法的核心逻辑高度重叠:都需要处理事务、关联rooms表、选择房间字段,并且都要过滤活跃状态的房间。我们可以把这些通用逻辑抽离成一个私有方法,然后让业务方法基于这个基础查询添加各自的特殊条件。

具体实现代码

第一步:提取通用查询构造函数

private buildActiveRoomsQuery(ctx?: ContextType) {
  return this.i.knex('users_rooms')
    .transacting(ctx?.transaction || null)
    .leftJoin('rooms', 'users_rooms.roomId', 'rooms.id')
    .select('rooms.*')
    .where('rooms.active', true);
}

第二步:改造原有业务方法

async getAllActiveRooms(ctx?: ContextType): Promise<RoomType[]> {
  // log getAllActiveRooms
  return this.buildActiveRoomsQuery(ctx);
}

async getActiveRoomsBySessionId(ctx?: ContextType, sessionId: number): Promise<RoomType[]> {
  // log getActiveRoomsBySessionId
  return this.buildActiveRoomsQuery(ctx)
    .where('users_rooms.sessionId', sessionId);
}

方案优势

  • 减少冗余代码:把重复的Knex查询链(事务处理、表关联、基础过滤)统一管理,避免多处修改的麻烦。
  • 职责更清晰:通用函数专注于构建基础查询,业务方法只需要处理各自的特殊过滤逻辑,代码可读性更强。
  • 扩展性拉满:如果后续需要新增类似查询(比如按用户ID查活跃房间),直接调用通用函数再加对应条件即可,不用重复写基础逻辑。

进阶灵活版(可选)

如果需要支持更复杂的动态查询调整,可以给通用函数加一个可选的回调参数,用来自定义修改查询:

private buildActiveRoomsQuery(
  ctx?: ContextType,
  queryModifier?: (query: Knex.QueryBuilder) => void
) {
  const query = this.i.knex('users_rooms')
    .transacting(ctx?.transaction || null)
    .leftJoin('rooms', 'users_rooms.roomId', 'rooms.id')
    .select('rooms.*')
    .where('rooms.active', true);

  queryModifier?.(query);
  return query;
}

// 调用示例
async getActiveRoomsBySessionId(ctx?: ContextType, sessionId: number): Promise<RoomType[]> {
  // log getActiveRoomsBySessionId
  return this.buildActiveRoomsQuery(ctx, (query) => {
    query.where('users_rooms.sessionId', sessionId);
  });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:36:44