• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    해결됨

이전 질문에 이어서 질문드립니다.

22.06.22 16:06 작성 조회수 280

0

 이전에 findEmail 과 같은 함수에서 promise allSettled를 사용해야 할지 질문했었는데 findEmail에 allSettled를 적용시키려고 시도해봤습니다. 이전 질문의 코드를 아래 처럼 재구성하였습니다.

await Promise.allSettled([
      this.authRepositry.isExistUserWithRealName(realName),
      this.authRepositry.isExistUserWithPhoneNumber(phoneNumber),
    ]).then((data) => {
      const errors = data.map((idx) =>
        idx.status === "rejected" ? idx.reason : false,
      );

      if (errors.includes(false)) {
        const foundWithRealName = data[0].value;
      }
      throw new BadRequestException(errors, "Find Email Error");
    });

allSettled 인자의 함수들에는 실명과 전화번호가 없을 시 에러를 내는 코드가 있고 에러가 있을시 rejected 상태의 인덱스를 errors 배열에 담고 아닐 시 false를 담습니다. 그리고 errors에 false값이 포함되어있다면 실명과 전화번호를 매치시켜 일치한다면 email을 리턴하게끔 하려 했습니다. 그런데 data변수가 PromiseRejectedResult라서 value속성이 없다 합니다. data[idx].value를 해야 value 안에 있는 id를 서로 비교 시킬수가 있는데 value를 사용할 수가 없습니다. 만약 콘솔로 찍어보면 "fullfiled" 라고 뜨기는 하는데 말이죠. 제가 디버그 콘솔을 자주 사용하는데 const foundWithRealName이 있는 라인에서 data[0].value를 찍어보면 정상적으로 User Entity값을 얻어올 수가 있습니다. 어떻게 좋은 방법이 없을까요?

답변 1

답변을 작성해보세요.

0

일단 await을 하시는데 왜 then을 붙이시나요? 여기서부터 문법 문제가 있고요.

const [nameResult, phoneNumberResult] = await Promise.allSettled

에러가 나는 상황에서 무엇을 하려고 하시는건지 잘 모르겠습니다.  allSettled 이후에서는 기존 allSettled 쓰기 전에 로직 그대로 쓰시면 됩니다. 데이터만 nameResult, phoneNumberResult에서 잘 꺼내서요.

이승훈님의 프로필

이승훈

질문자

2022.06.22

흠.. 확실히 await이랑 then을 같이 쓰는건 제가 실수했었네요. 그런데도 제가 말했었던 status가 fullfield 일 때 value프로퍼티를 사용못하는건 변함이 없네요. 제가 작성한 코드 보여드릴게요.

const { realName, phoneNumber } = findEmailDto;

    const promises = await Promise.allSettled([
      this.authRepositry.isExistUserWithRealName(realName),
      this.authRepositry.isExistUserWithPhoneNumber(phoneNumber),
    ]);
    const errors = promises.filter((idx) => idx.status === "rejected");

    if (errors.length)
      throw new BadRequestException(errors, "Find Email Error");

    const [realNameResult, phoneNumberResult] = promises;

    console.log(realNameResult.value); 
    console.log(phoneNumberResult.value);

  value에 빨간줄이 그어져 있는데 에러 메세지는 각각 같습니다.

Property 'value' does not exist on type 'PromiseSettledResult<UserEntity>'.
  Property 'value' does not exist on type 'PromiseRejectedResult'.

만약 value 대신 status가 "rejected"일 때 사용 할 수 있는 reasone을 사용하면 위와 유사한 에러가 납니다.

Property 'reason' does not exist on type 'PromiseSettledResult<UserEntity>'.
  Property 'reason' does not exist on type 'PromiseFulfilledResult<UserEntity>'.

 

  혹시나 해서 await 대신 then도 한번 사용해봤지만 결과는 같습니다.

 const { realName, phoneNumber } = findEmailDto;

    const promises = Promise.allSettled([
      this.authRepositry.isExistUserWithRealName(realName),
      this.authRepositry.isExistUserWithPhoneNumber(phoneNumber),
    ]);

    promises.then((data) => {
      const errors = data.filter((idx) => idx.status === "rejected");

      if (errors.length)
        throw new BadRequestException(errors, "Find Email Error");

      const [realNameResult, phoneNumberResult] = data;

      console.log(realNameResult.value);
      console.log(phoneNumberResult.value);
    });

 

 

타입스크립트 특성상 if (errors.length) throw 한다고 해서 그 아래가 PromiseFulfilledResult만 남는다고 보장되지 않습니다.

  const isRejected = (input: PromiseSettledResult<unknown>): input is PromiseRejectedResult => input.status === 'rejected';
  const isFulfilled = <T>(input: PromiseSettledResult<T>): input is PromiseFulfilledResult<T> => input.status === 'fulfilled';

  const promises = await Promise.allSettled([Promise.resolve('a'), Promise.resolve('b')]);
  const errors = promises.filter(isRejected);
  if (errors.length) throw new Error('error');
  const result = promises.filter(isFulfilled);
  const [realNameResult, phoneNumberResult] = result;
  // ...
이승훈님의 프로필

이승훈

질문자

2022.06.22

직접 코드까지 알려주시니 감사합니다! 근데 여기서 궁금한게 있는데 isRejected와 isFullfield 함수의 리턴값 타입 부분에서 is 뒤에 PromiseRejectedResult,PromiseFulfilledResult<T> 명시해 주셨는데 input 매개변수는 PromiseRejectedResult,PromiseFulfilledResult<T> 이다. 이런식으로 명시해주기 위해 사용하나요? as 는봤어도 is는 처음보네요.

타입가드입니다. 타입가드는 타입스크립트 이해에 필수적으로 알고 계셔야 하는 겁니다. 타입스크립트 공식문서 정독하세요!