스레드와 큐 (while문 내의 callback)

이승훈·2022년 11월 8일
0

TIL

목록 보기
17/32
post-thumbnail

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

기존 코드

let discrimination = '';

while (discrimination !== "3스트라이크") {
  MissionUtils.Console.readLine("숫자를 입력해주세요 : ", (answer) => {
    const usersInput = answer;
    const userNumbersArr = this.stringToArrConverter(usersInput);
    const refNumbersArr = this.refNumbersGetter();
    let discrimination = this.discriminator(userNumbersArr, refNumbersArr);
    this.printer(discrimination);
  });
}
MissionUtils.Console.readLine('콘솔창에 띄울 문구', (사용자입력값) => {
	사용자 입력값 가지고 지지고 볶는 함수의 내용
})

위의 MissionUtils.Console.readLinde 메소드는 콘솔창에 문구를 먼저 띄운 뒤 사용자의 입력값을 인자로 받아 그 다음의 콜백함수를 실행시키는 메소드이다.

기존 의도

  1. '숫자를 입력해주세요' 문구 콘솔창에 띄우기
  2. 나의 입력을 기다리며 다음 반복은 일어나지 않음
  3. 입력이 완료되면 콜백함수가 실행되고 discrimination이 '3스트라이크' 인지 판단 후 반복문 실행

실제 동작

콜백함수의 실행이 완료되길 기다리지 않고 반복문이 계속해서 실행
즉, '숫자를 입력해주세요' 문구가 콘솔창에 계속 빛의속도로 출력됨
내가 뭐 입력을 할 수가 없음.

잘못된 원인

콜백함수는 스레드에서 즉각 시행되지 않고 Web APIs(background)를 거쳐 Callback Queue(Task Queue)에 들어간 후, Stack이 비워진 후에야 하나하니씩 시행이 되기 때문이다.

그러니 콜백함수가 실행되길 기다리지 않고 WebApis에 계속해서 콜백함수만 쌓여가고 있는것이다.

개선 사항

aync, await를 사용하여 나의 입력을 받은 후 다음 명령을 실행하도록해줄 수 있지만 테스트코드를 수정할 수 없기에 그 방법은 철회하였다.

그렇다면 입력을 받은 후 3 스트라이크가 안될 경우 다시 MiddionUtils.Console.readLine을 실행시키도록 재귀함수의 방법을 사용하도록 하였다.

개선 코드

  gameStarter(refNumbersArr) {
    let discrimination = "";

    MissionUtils.Console.readLine("숫자를 입력해주세요 : ", (answer) => {
      const usersInput = answer;
      const userNumbersArr = this.stringToArrConverter(usersInput);
      let discrimination = this.discriminator(userNumbersArr, refNumbersArr);
      this.printer(discrimination);

      if (discrimination !== "3스트라이크") {
        this.gameStarter(refNumbersArr);
      } else if (discrimination === "3스트라이크") {
        this.printer("3개의 숫자를 모두 맞히셨습니다! 게임 종료");
        this.reStartSelector();
      }
    });
  }
profile
Beyond the wall

0개의 댓글