안녕하세요. 이번 포스팅은 간단한 게임을 만들어보면서 async, await 개념을 알아보겠습니다.
up & down 게임을 아시나요? 술자리에서 많이 했던 게임인데 수의 범위(1~100)을 정하고 주어진 기회 안에 수를 맞추는 게임이죠.
이 게임을 통해 async, await을 알아볼게요.
게임 조건은 다음과 같습니다.
1. 1 ~ 100까지의 수 중에서 랜덤으로 값을 뽑습니다.
2. 사용자는 10번의 기회가 주어지고 수를 입력합니다. 기회는 원하는대로 줘도 됩니다.
3. 사용자가 입력한 수보다 랜덤 값이 크면 'up'을 사용자에게 알려주고 반대면 'down'을 알려줍니다.
4. 10번의 기회를 모두 소진하거나 정답을 맞출 시 게임은 종료됩니다.
우선 1번의 게임 조건을 만족시키기 위해 1 ~ 100까지의 수를 추출하는 코드를 작성합니다.
그리고 기회를 나타내는 life, 몇 번째 시도 중인지 나타내는 count를 선언합니다.
let target = Math.floor(Math.random() * 100) + 1; // 1 ~ 100 랜덤
let life = 10;
let count = 0;
async, await을 사용하기 위해서는 Promise 객체를 반환하는 함수가 필요합니다.
그래서 게임 조건 2, 3번을 만족하면서 Promise 객체를 반환하는 함수를 만들어보겠습니다.
let target = Math.floor(Math.random() * 100) + 1; // 1 ~ 100 랜덤
let life = 10;
let count = 0;
var check = () => {
return new Promise((resolve, reject) => {
let answer = parseInt(prompt("1 ~ 100 사이의 숫자를 입력하세요"));
if (target === answer)
resolve(++count);
if (target > answer) {
console.log('up!');
life--;
count++;
reject(answer);
}
if (target < answer) {
console.log('down!');
life--;
count++;
reject(answer);
}
});
}
check라는 함수를 만들었습니다.
check 함수는 사용자가 입력한 값이 랜덤 값과 일치한지, 보다 큰지, 보다 작은지를 판단하여 Promise 객체를 반환하는 역할을 합니다.
let target = Math.floor(Math.random() * 100) + 1; // 1 ~ 100 랜덤
let life = 10;
let count = 0;
var check = () => {
return new Promise((resolve, reject) => {
let answer = parseInt(prompt("1 ~ 100 사이의 숫자를 입력하세요"));
if (target === answer)
resolve(++count);
if (target > answer) {
console.log('up!');
life--;
count++;
reject(answer);
}
if (target < answer) {
console.log('down!');
life--;
count++;
reject(answer);
}
});
}
var startGame = async () => {
while (true) {
if (life === 0) {
console.log(`게임 종료! 정답은 ${target}입니다.`);
break;
}
//check 함수는 Promise 객체를 반환하므로 await 사용가능
let result;
try {
result = await check(); // resolve
console.log(`정답입니다! ${result}번만에 맞추셨어요.`);
break;
} catch (answer) { // await에서 발생한 에러(Promise가 reject를 반환하는 경우)는 모두 아래 catch 블록에 걸린다.
console.log(`${answer}은 오답입니다. 기회는 ${life}번 남았습니다.`);
}
}
}
startGame();
startGame 게임이라는 비동기 함수를 만들었습니다.
async 키워드가 붙었기 때문에 해당 함수는 비동기로 동작합니다.
중간에 보시면 try, catch문이 있는데요. try 문에는 await 키워드를 통해 check 함수를 호출합니다.
단, 주의할 점은 함수에 await 키워드를 사용하기 위해서는 함수의 리턴값이 반드시 Promise 객체여야만 가능합니다.
check 함수 구현부에 보면 사용자가 입력한 값과 랜덤 값이 일치하면 resolve를 호출합니다.
이 호출된 resolve가 await check() 부분의 리턴값으로 반환되어 result라는 변수에 담깁니다.
만약 사용자가 입력한 값과 랜덤 값이 일치하지 않으면 reject를 호출합니다.
이 호출된 reject는 catch문에 걸리게 됩니다.
async, await을 위처럼도 가능하지만 then, catch을 섞어서 사용할 수도 있습니다.
왜냐하면 check 함수는 Promise 객체를 반환하기 때문이죠.
var startGame = async () => {
while (true) {
if (life === 0) {
console.log(`게임 종료! 정답은 ${target}입니다.`);
break;
}
// async, await과 then, catch를 혼용해서 사용할 수 있다.
await check()
.then((count) => {
console.log(`정답입니다! ${count}번만에 맞추셨어요.`);
})
.catch((answer) => {
console.log(`${answer}은 오답입니다. 기회는 ${life}번 남았습니다.`);
});
}
}
startGame();
게임을 플레이해보겠습니다.
5번만에 맞췄습니다.
'Programming > Javascript' 카테고리의 다른 글
[Javascript] 이벤트 루프 동작과정에 대한 이해 (0) | 2021.07.25 |
---|---|
fetch API를 사용하여 코드 라인 수를 줄여보자 (0) | 2021.05.13 |
[Javascript] ES6 export, import (0) | 2021.01.08 |
[Javascript] ES6 Promise를 통해 콜백지옥 문제를 해결해보자 (0) | 2021.01.06 |
[Javascript] ES6 Destructuring 문법에 대해 알아보자 (0) | 2020.12.30 |