JS는 싱글 스레드다. 시간이 걸리는 작업(네트워크, 타이머, 파일 IO) 중에 멈춰서 기다리지 않고, "끝나면 이걸 실행해줘"라고 예약만 해두고 다음 코드로 넘어간다. Rust의 Future와 개념적으로 동일하다 — 다만 JS의 Promise는 만드는 즉시 실행이 시작된다(lazy가 아니라 eager).
// 콜백을 중첩하면 "콜백 지옥"이 된다
readSensor((err, a) => {
if (err) return handleError(err);
readSensor((err, b) => {
if (err) return handleError(err);
// 들여쓰기가 계속 깊어짐...
});
});
function readSensor() {
return new Promise((resolve, reject) => {
const delay = Math.random() * 500;
setTimeout(() => {
if (Math.random() < 0.2) {
reject(new Error("센서 응답 없음"));
} else {
resolve(52.3 + Math.random() * 30);
}
}, delay);
});
}
readSensor()
.then((temp) => console.log(`읽음: ${temp}°C`))
.catch((err) => console.error("실패:", err.message))
.finally(() => console.log("완료 (성공이든 실패든)"));
// then 체이닝 — 각 then은 새 Promise를 리턴하므로 계속 이어붙일 수 있다
readSensor()
.then((temp) => temp * 9/5 + 32)
.then((f) => console.log(`화씨: ${f}`));
Promise.all([readSensor(), readSensor(), readSensor()])
.then(([a, b, c]) => console.log("셋 다 성공:", a, b, c))
.catch((err) => console.error("하나라도 실패하면 여기로:", err.message));
// 하나 실패해도 나머지 결과를 보고 싶으면 Promise.allSettled
Promise.allSettled([readSensor(), readSensor()])
.then((results) => results.forEach((r) => console.log(r.status, r.value ?? r.reason)));
_submissions/day10.js과제 1. readSensor 구현
위 예제와 동일한 readSensor()를 직접 작성한다: 100~400ms 사이 랜덤 지연 후, 20% 확률로 reject, 80% 확률로 40~90 사이 랜덤 온도로 resolve.
과제 2. then/catch 사용
logReading(): readSensor()를 호출해서 성공하면 "온도: N°C"를, 실패하면 "에러: 메시지"를 콘솔에 출력한다 (then/catch 사용, async/await 아직 쓰지 말 것 — Day 11에서 배움).
과제 3. 3개 동시 읽기
readAllSensors(): Promise.all로 readSensor() 3번을 동시에 호출하고, 성공하면 평균값을, 하나라도 실패하면 "일부 센서 읽기 실패"를 출력한다.
과제 4 (도전). 타임아웃 달기
withTimeout(promise, ms): 주어진 promise가 msms 안에 안 끝나면 "timeout" 에러로 reject하는 새 Promise를 리턴한다. (힌트: Promise.race로 원래 promise와 타이머 promise를 경쟁시킨다)
cd ~/Documents/javascript-2주완성
bun _grade.ts day10