본문 바로가기

upco #3. GeoAPI 와 user DB 연결 & Promise.all 본문

개발/프로젝트

upco #3. GeoAPI 와 user DB 연결 & Promise.all

자전하는명왕성 2023. 3. 20. 23:23

포스팅 분량이 그리 많지 않다.

 async findLocation({
    interest,
    findAroundUsersInput,
  }: IMapServiceFindLocation): Promise<IUserWithLocation[]> {
  // 중략 // 
    const aroundUsers = await client.georadius(
      "geoSet",
      centerLng,
      centerLat,
      radius,
      "km",
      "withCoord",
    );

  // 여기서부터
    const userIds = aroundUsers.map((el) => (el = el[0])); // 유저 아이딧값만 매핑
    const locationByUsers = aroundUsers.map((el) => (el = el[1])); // 유저 위칫값만 매핑
  // 여기서 slice를 쓰는 이유는, geoAPI 를 거치고 나면 위도 & 경도값이 소숫점 10자리까지 무작위로 반환되기 때문이다.
    locationByUsers.forEach((location) => {
      location[0] = location[0].slice(0, 10);
      location[1] = location[1].slice(0, 10);
    });

  // 해당 getUserInfo 로직은 밑에 있다.
    return this.getUsersInfo(userIds, locationByUsers);
  }
  
    async getUsersInfo(userIds: string[], locationByUsers: IlocationByUser) {
      const promisedUsers = await Promise.all(
        userIds.map((id) => this.userService.findOneById({ id })),
      );

      const usersWithLocation: IUserWithLocation[] = promisedUsers.map(
        (user, idx) => ({
          ...user,
          lat: locationByUsers[idx][1],
          lng: locationByUsers[idx][0],
        }),
      return promisedUsers;
  }

 

여기서 user.service 를 주입받아 사용하는 것은 흔하게 사용되는 것이지만, 다수의 유저 정보를 가져오기 위해 Promise.all을 사용했다.

promise.all은 여러 개의 promise 객체를 인자로 받아, 모든 promise 가 완료될 때까지 기다린 다음에 결과를 반환하는 메서드다.

중요한 점은, promise.all 메서드를 통해 반환되는 값들은 배열에 담겨 전달되는데,

이때 배열 관련 메서드를 사용하여 데이터를 원하는대로 가공할 수 있다는 장점을 가진다. (여기서는 forEach를 사용)

 

위와 같은 로직을 완성할 경우, 아래와 같은 데이터를 얻을 수 있게 된다.

 

ps. 결괏값을 자세히 보니, 데이터가 보여주는 위도가 소숫점 일곱 짜리까지 반환되고 있다.

대한민국은 위도가 최대 39까지라, slice 메서드를 수정하여 6자리까지만 보여지도록 해야겠다.

 

Comments