사이드 프로젝트 하면서 배운점 1

훈이·2023년 1월 25일
0
post-custom-banner

사이드 프로젝트에서 코드를 작성하며 배운점을 블로그에 정리하려고 한다.
나는 현재 부트캠프 동기들과 사이드 프로젝트를 진행하고 있으며 주제는 통합 인력관리 솔루션인 시프티(링크)를 클론 코딩하는 중이다.

나는 현재 출퇴근기록API, 근무일정API, 공지사항게시판API, 근무일정템플릿API, 근무일정유형API, 멤버API를 맡고있다.

  async weekFind({ today, organizationId, roleCategoryId }) {
    const week = currentWeek(today);
    const startWeek = new Date(week[0]);
    const end = new Date(week[1]);
    const endWeek = new Date(end.setDate(end.getDate() + 1));

    const result = [];

    await Promise.all(
      organizationId.map(async (organizationId) => {
        await Promise.all(
          roleCategoryId.map(async (roleCategoryId) => {
            const schedule = await this.scheduleRepository
              .createQueryBuilder('Schedule')
              .leftJoinAndSelect('Schedule.member', 'member')
              .leftJoinAndSelect('Schedule.organization', 'organization')
              .leftJoinAndSelect('Schedule.roleCategory', 'roleCategory')
              .leftJoinAndSelect(
                'Schedule.scheduleTemplate',
                'scheduleTemplate',
              )
              .leftJoinAndSelect('Schedule.company', 'company')
              .leftJoinAndSelect(
                'Schedule.scheduleCategory',
                'scheduleCategory',
              )
              .where('Schedule.organization = :organizationId', {
                organizationId,
              })
              .andWhere('Schedule.roleCategory = :roleCategoryId', {
                roleCategoryId,
              })
              .andWhere(
                `Schedule.date BETWEEN '${startWeek.toISOString()}' AND '${endWeek.toISOString()}'`,
              )
              .orderBy('member.name', 'ASC')
              .addOrderBy('Schedule.date', 'ASC')
              .getMany();

            result.push(schedule);
          }),
        );
      }),
    );

    return result.flat();
  }
  
  // 
  const currentWeek = (today) => {
    today = new Date(today);
    const sunday = today.getTime() - 86400000 * today.getDay();

    today.setTime(sunday);

    const week = [today.toISOString().slice(0, 10)];

    for (let i = 1; i < 7; i++) {
        today.setTime(today.getTime() + 86400000);
        week.push(today.toISOString().slice(0, 10));
    }

    return [week[0], week[week.length - 1]];
};

위 의 코드는 근무일정API에서 오늘 날짜를 받은 뒤 currentWeek라는 함수에서 오늘 날짜를 기준으로 일주일을 계산한 뒤 일주일의 첫 시작날과 마지막날을 반환한 뒤 쿼리빌더의 BETWEEN을 사용하여 일주일 사이의 organazationId(지점Id), roleCategoryId(직무Id)와 일치하는 결과를 조회하는 로직이다.

위 코드의 문제점은 organizationId와 roleCategoryId가 배열로 들어오는데 내가 코드를 짜면서 생각했던 점은 처음 organizationId 배열에서 map을 돌리고 organization(지점)안에 roleCategory(직무)가 있으니 map 안에서 또 map을 돌려 조건에 맞는 결과들을 result라는 빈 배열안에 push를 해주고 결과값으로 반환 해주었다.

위 코드의 문제점은 Promise.all안에 map이 그 안에 또 Promise.all과 map이 있어서 조회 속도가 느리다는 단점이 있엇다.

그래서 리팩토링을 해야한다는 생각이 있었고 아래의 코드와 같이 바꾸게 되었다.

async weekFind({ today, organizationId, roleCategoryId }) {
    const week = currentWeek(today);
    const startWeek = new Date(week[0]);
    const end = new Date(week[1]);
    const endWeek = new Date(end.setDate(end.getDate() + 1));

    const schedules = await this.scheduleRepository
      .createQueryBuilder('Schedule')
      .leftJoinAndSelect('Schedule.member', 'member')
      .leftJoinAndSelect('Schedule.organization', 'organization')
      .leftJoinAndSelect('Schedule.roleCategory', 'roleCategory')
      .leftJoinAndSelect(
        'Schedule.scheduleTemplate',
        'scheduleTemplate',
      )
      .leftJoinAndSelect('Schedule.company', 'company')
      .leftJoinAndSelect(
        'Schedule.scheduleCategory',
        'scheduleCategory',
      )
      .where('Schedule.organization IN (:...organizationId)', { organizationId })
      .andWhere('Schedule.roleCategory IN (:...roleCategoryId)', { roleCategoryId })
      .andWhere(
        `Schedule.date BETWEEN '${startWeek.toISOString()}' AND '${endWeek.toISOString()}'`
      )
      .orderBy('member.name', 'ASC')
      .addOrderBy('Schedule.date', 'ASC')
      .getMany();

    return schedules;
}

중첩되었던 Promise.all 과 map을 제거하고 쿼리빌더의 IN을 이용하여 where조건으로 넣는것으로 바꿧다. 그 결과 조회속도가 처음 코드보다 한결 나아진걸 느낄 수 있었다.

profile
백엔드 개발자가 되자!
post-custom-banner

0개의 댓글