Promise와 async await

이승훈·2022년 11월 8일
0

TIL

목록 보기
16/31
post-thumbnail

우테코 5기 프로코스 2주차 문제를 푸는과정 중 맞닥뜨린 문제와 그에 대한 해결 과정을 기술하였다.
문제 상황 : 콜백함수의 동기적 블로킹을 진행해야하는 상황

기존 코드

(App.js)


const userNumbersGetter = () => {
  	let userNumber;
    MissionUtils.Console.readLine("숫자를 입력해주세요 : ", (asnwer) => {
		userNumber = answer;
    });
  	return userNumber
};

class App {
  play() {
    MissionUtils.Console.print("숫자 야구 게임을 시작합니다.");
    const userNumbers = userNumbersGetter();
    console.log("userNumbers : ", userNumbers);
  }
}

const app = new App();
app.play();

module.exports = { App, discriminator };

Node App.js를 실행후 App 클래스의 play메소드를 실행해주었다.

기존 의도

  1. 콘솔창에 '숫자 야구 게임을 시작합니다.' 출력
  2. userNumbersGetter 함수 실행
  3. 콘솔창에 '숫자를 입력해주세요' 출력 후 나의 입력을 대기
  4. 내가 숫자를 입력해주면 그 숫자를 받아서 userNumbersGetter함수의 return값으로 입력
  5. userNumbersGetter함수 종류 후 userNumbers에 함수의 return값 입력
  6. 콘솔창에 userNumbers(내가 입력한 값) 출력

실제 동작

  1. 콘솔창에 '숫자 야구 게임을 시작합니다.' 출력
  2. userNumbersGetter 함수 실행
  3. 콘솔창에 '숫자를 입력해주세요' 출력
  4. 내 입력을 대기하지 않고 바로 userNumbers 콘솔창에 출력
    -> 콘솔창엔 undefined가 나옴

잘못된 원인

함수1내에서 또다른 함수1-1를 실행시켰고 그 함수1-1의 콜백함수가 실행된 후 함수 2가 실행될거라 생각하였다.
즉, javascript는 동기적으로 위에서 아래로 순서대로 코드가 실행되지만
non-blocking으로 실행되었기 때문에 아래의 코드에서 userNumbersGetter 함수 안의 코드의 실행완료여부와 별개로
console.log("userNumbers : ", userNumbers); 를 이어서 바로 실행 시켜버린것이다.

const userNumbers = userNumbersGetter();
console.log("userNumbers : ", userNumbers); 

개선 사항

userNumbers가 userNumbersGetter의 값을 받기 전까지 다음 코드가 실행되지 않도록 만들어주어야했다.
(blocking해준다는 의미로 현재는 이해하고 있다.)
이를 위해서 userNumbersGetter() 함수는 promise타입의 데이터를 return 해주도록 하였고
play() 메소드안에서 promise 타입의 데이터가 처리될 때 까지 기다려주기 위해 async, await를 사용하였다.

개선 코드

const userNumbersGetter = () => {
  return new Promise((resolve, reject) => {
    MissionUtils.Console.readLine("숫자를 입력해주세요 : ", (asnwer) => {
      resolve(asnwer);
    });
  });
};

class App {
  async play() {
    MissionUtils.Console.print("숫자 야구 게임을 시작합니다.");
    const userNumbers = await userNumbersGetter();
    console.log("userNumbers 최종 성공 여부 : ", userNumbers);
  }
}

const app = new App();
app.play();

module.exports = { App, discriminator };

잊지 말아야 할 점

new Promise() 생성자를 통해 promise 타입 데이터를 생성해줄 때
기본적인 형태는 아래와 같다.

const job1 = new Promise((resolve, reject) => {
  resolve(성공했을 때 return 해줄 data를 이곳에 넣어주면 job1으로 return)
  reject(실패했을 때 return 해줄 data를 이곳에 넣어주면 job1으로 return)
})
profile
Beyond the wall

2개의 댓글

comment-user-thumbnail
2022년 11월 19일

브릿지 문제 풀다가 막혀서 구글링하다보니 여기네요.. ㅋ 화이팅

1개의 답글