promise 에서 break처럼 나갈 방법이 없나요?

조회수 3543회

Javascript(node express) 에서 Promise를 진행하다가 중간에 탈출할 방법이 있을까요? db에서 값을 얻고 결과값이 아무것도 없으면 다시 다른 sql을 사용하여 값을 얻도록 하고 싶은데요.
 처음 db에서 읽어오는 과정을 read_data_first이라고 하고, 읽어온 datas값을 파싱해서 결과값으로 리턴해주는 것을 parse_data_first 로 하고, 다시 다른 sql문을 쓰는 경우에는 read_data_second, parse_data_second라고 조금 이해 하시기 쉽게 묶 보았습니다 promise로 로직을 만들었을 때 read_data_first가 성공하면 parse_data_first만 실행하고 실패하면 read_data_second 실행하고 parse_data_second를 실행하고 싶습니다. 
그런데 read_data_first가 성공하면 밑에 있는 parse_data_second까지 실행되어서 제가 의도한 것과는 다르게 실행됩니다.

// 이 함수 안에서 데이터가 있는지 확인해 없으면 reject(‘not_exist’) 를 보냅니다.

read_data_first() 

.then(parse_data_first)

.catch(
if(err.message===‘not_exist’){
    read_data_second();

}else{

    next(err)// 진짜 에러가 날수도 잇으니까

})

.then(
parse_data_second();
)

.catch(
next(err);
)

`. 원하는 부분에서 완전히 promise 진행을 끝낼 수 있는 방법이 없을까요? 예를들어 parse_data_first를 완료했다면 promise를 끝내라 이런거(return을 하면 다음 then으로 넘어갈 뿐이더라고요)

  1. 이런 로 보통 promise라는 용도와 맞지 않는건가요? 원래는 그냥 콜백 안에 또 if문으로 콜백을 작성하는 형식으로 작성했었습니다. 하지만 만약 체크해야하는 경우가 세개가 생기면 콜백안에 콜백이 들어가서 복잡해 지지 않을까 해서 바꿔보고 싶었습니다 ㅜㅜ 콜백지옥이 아니면서 해결할 좋은 방법이 있다면 알려주시면 감사하겠습니다 :]
  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 원래 프라미스는 atomic 동작하는 작업에서 많이 쓰입니다.

    만약 원하는 부분에서 강제 종료되게 하려면 그 함수 내부에서 throw new Error('reason')을 호출하여 강제로 catch 함수로 넘기는 방법이 있습니다.

    다만 주의할 점은, catch()는 thenable 중간에는 쓰지말고 취소하고 싶은 로직들을 쭉 나열한 이후 마지막에만 써야 한다는 겁니다.

    예를 들어 아래와 같은 코드가 있고

    promise
    .then(func1)
    .then(func2)// raise exception!!
    .then(func3)
    .catch(handle1)
    .then(func4)
    .then(func5);
    

    func2에서 예외가 발생한다면

    func1 => func2의 예외 발생 전까지의 코드 일부 => handle1 => func4 => func5

    순으로 실행 됩니다. func3은 건너 뛰는 거죠.

    따라서 atomic한 실행을 보장해야 하는 것들은 인접하여 thenable로 체이닝을 시켜주시고 개별 단계에 대한 exception들은 하나의 catch()에서 미리 정의해둔 에러 값의 종류들을 확인하여 한 번에 해 주셔야 합니다.

    제가 테스트해본 코드 첨부합니다.

    const wait = new Promise((resolve, reject)=>{
      const duration = 1000 + Math.random() * 4000;    
      setTimeout(()=> {
        resolve(duration);
      }, duration);
    });
    
    wait.then(()=>{
      console.log('first');
    })
    .then(()=>{
      console.log('second');
      throw new Error('on second');
    })
    .then(()=>{
      console.log('third');
    })
    .then(()=>{
      console.log('fourth');
    })
    .catch((err)=>{
      console.log(err)
    })
    .then(()=>{
      console.log('fifth');
    })
    .then(()=>{
      console.log('sixth');
    });
    

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)