강의 설명 중에 헷갈리는 것이 있네요
2:31 부터 동기, 비동기 설명이 서로 반대로 되어있는 거 같은데 혹시 제가 잘못 이해하고 있는걸까요?
저는 설명해주신거랑 반대로 이해하고 있긴 해서요
답변 2
0
안녕하세요, haseung님. 우선 답변이 많이 늦어져 정말 죄송합니다.
말씀해 주신 타임라인(2분 31초 전후)의 강의 내용을 다시 꼼꼼히 확인하고 있습니다.
haseung 님 께 혼선 없이 확실하게 개념을 잡고 넘어가실 수 있도록 정확하게 짚어드리고자 하는데요, 실례가 되지 않는다면 강의에서 언급된 어떤 구체적인 설명이나 예시가 기존에 알고 계시던 개념과 다르게 느껴지셨는지 조금 더 자세히 남겨주실 수 있을까요? 이해하고 계신 내용과 어떤 차이가 있었는지 함께 공유해 주시면, 영상 속 맥락과 대조하여 명쾌하게 정리해 드리겠습니다.
아울러 소중한 학습 흐름에 혼선을 드리고 답변까지 지체된 점이 너무 죄송스러워 작은 보답을 준비했습니다. jeony0535@naver.com으로 편하게 이메일 한 통 남겨주시면, 개설된 전 강의에 적용 가능한 최대 할인 쿠폰을 전달해 드리겠습니다.
편하실 때 언제든 답변 남겨주세요. 빠르게 확인 후 도움드리겠습니다. 감사합니다!
0
영상에 나와있는 비유를 보면 열쇠가 올 때까지 기다렸다가 받아야 한다는 행동을 비동기라고 하셨는데, 제가 알고 있는 비동기는 기존에 하던 작업에 다른 작업이 끼어들어도 방해받지 않고 병렬적으로 수행할 수 있다인데 잘못 생각하고 있는건지 궁금합니다.
0
안녕하세요, haseung님!
먼저 강의를 꼼꼼하게 수강해 주시고, 이해가 되지 않는 부분을 직접 질문해 주셔서 진심으로 감사드립니다. 😊
말씀해 주신 2분 31초 부근의 설명을 다시 확인해 보니, 충분히 혼동하실 수 있는 부분이 있었습니다.
결론부터 말씀드리면, haseung님께서 기존에 이해하고 계셨던 동기(Synchronous)와 비동기(Asynchronous)의 개념이 잘못된 것은 아닙니다. 오히려 제가 강의에서 사용한 비유가 두 개념의 차이를 명확하게 전달하지 못한 부분이 있습니다.
강의에서는 동기 방식을 우편함에서 편지를 즉시 꺼내는 것으로, 비동기 방식을 우체부가 올 때까지 기다렸다가 편지를 받는 것으로 설명했습니다. 그런데 엄밀히 말하면 이러한 비유는 동기와 비동기의 차이를 설명하기에 적절하지 않습니다.
동기와 비동기의 핵심은 단순히 기다리느냐, 기다리지 않느냐의 차이가 아니라, 어떤 작업의 완료를 기다리는 동안 다른 작업을 진행할 수 있는지, 그리고 작업의 완료와 이후 실행이 어떤 관계를 갖는지에 있습니다.
조금 더 쉽게 설명드리겠습니다.
먼저 일반적인 동기적 코드 실행에서는 앞선 작업을 완료한 후 다음 작업으로 넘어갑니다.
console.log("첫 번째 작업");
console.log("두 번째 작업");
console.log("세 번째 작업");위 코드는 첫 번째, 두 번째, 세 번째 작업이 순서대로 실행됩니다. 각 문장이 실행을 마쳐야 다음 문장을 실행하는 구조입니다.
반면 비동기 처리는 시간이 걸리는 작업을 시작한 뒤, 그 결과가 준비되기를 기다리는 동안 다른 작업을 진행할 수 있도록 구성하는 방식입니다.
console.log("첫 번째 작업");
setTimeout(() => {
console.log("두 번째 작업");
}, 2000);
console.log("세 번째 작업");위 코드를 실행하면 다음과 같은 결과가 나타납니다.
첫 번째 작업
세 번째 작업
두 번째 작업두 번째 작업은 타이머를 통해 나중에 실행되도록 예약되어 있기 때문에, JavaScript는 타이머가 완료될 때까지 멈춰 있지 않고 세 번째 작업을 먼저 실행할 수 있습니다.
여기서 중요한 점은 비동기 처리라고 해서 기다리는 과정 자체가 사라지는 것은 아니라는 사실입니다.
비동기 작업에서도 결과가 필요한 순간에는 기다려야 할 수 있습니다. 다만 그 기다림이 프로그램의 다른 모든 작업까지 반드시 중단시키는 것은 아닙니다.
이 부분을 이해하시면 강의에서 등장한 async와 await도 조금 더 명확하게 이해하실 수 있을 것 같습니다.
예를 들어 다음 코드를 살펴보겠습니다.
async function example() {
console.log("첫 번째 작업");
await new Promise((resolve) => {
setTimeout(resolve, 2000);
});
console.log("두 번째 작업");
}
example();
console.log("세 번째 작업");실행 결과는 다음과 같습니다.
첫 번째 작업
세 번째 작업
두 번째 작업여기서 await는 Promise가 완료될 때까지 해당 함수의 이어지는 실행을 일시적으로 중단합니다.
따라서 example() 함수 내부에서는 첫 번째 작업 이후 두 번째 작업으로 바로 넘어가지 않습니다. Promise가 완료된 뒤에야 두 번째 작업을 실행합니다.
그렇지만 JavaScript 프로그램 전체가 멈추는 것은 아닙니다. example() 함수가 기다리는 동안 함수 바깥에 있는 세 번째 작업은 정상적으로 실행될 수 있습니다.
즉, await를 사용해서 특정 비동기 작업의 결과를 기다리는 것과 프로그램 전체의 실행을 멈추는 것은 서로 다른 개념입니다.
그렇다면 여기서 한 가지 의문이 생길 수 있습니다.
비동기의 장점이 다른 작업을 진행할 수 있다는 것이라면, Next.js 15에서는 왜 기존에 바로 접근할 수 있었던 searchParams를 굳이 Promise 형태로 변경하고 await를 사용하도록 했을까요?
이 부분이 이번 강의에서 전달하고자 했던 핵심 내용입니다.
Next.js 14까지는 일반적으로 searchParams가 일반 객체로 제공되었기 때문에 다음과 같이 속성에 직접 접근할 수 있었습니다.
export default function Page({ searchParams }) {
const sort = searchParams.sort;
return <div>{sort}</div>;
}하지만 Next.js 15에서는 searchParams가 Promise 형태로 제공되도록 변경되었습니다.
interface PageProps {
searchParams: Promise<{ sort?: string }>;
}
export default async function Page({
searchParams,
}: PageProps) {
const { sort } = await searchParams;
return <div>{sort}</div>;
}여기서 await searchParams는 Promise가 완료된 후 실제 쿼리 파라미터 값을 가져오겠다는 의미입니다.
그런데 이 변경은 단순히 기존에 빠르게 접근하던 데이터를 일부러 느리게 가져오도록 만들었다는 의미가 아닙니다.
Next.js는 페이지를 렌더링할 때 사용자 요청에 따라 달라지는 정보와, 사용자 요청에 관계없이 미리 준비할 수 있는 정보를 구분할 필요가 있습니다.
예를 들어 쇼핑몰 페이지를 생각해 보겠습니다.
쇼핑몰의 로고, 기본 메뉴, 공통 안내 문구는 사용자가 어떤 정렬 옵션을 선택하더라도 동일하게 표시할 수 있습니다.
반면 상품 목록은 사용자가 ?sort=asc를 선택했는지, ?sort=desc를 선택했는지에 따라 달라질 수 있습니다.
따라서 모든 부분이 사용자 요청 정보를 필요로 하는 것은 아닙니다.
이러한 상황에서 요청별 정보가 필요한 부분과 그렇지 않은 부분을 명확하게 구분할 수 있다면, 요청 정보와 관계없는 부분은 미리 준비하고 실제로 해당 정보가 필요한 부분에서만 그 결과를 기다리는 구조를 만들 수 있습니다.
Next.js 15에서 searchParams를 비롯한 요청 관련 API를 비동기 방식으로 변경한 것은 이러한 렌더링 구조를 더욱 유연하게 지원하기 위한 설계적인 변화입니다.
또한 이러한 구조는 Suspense 및 스트리밍(Streaming) 같은 기능과 연결될 수 있습니다.
예를 들어 상품 목록을 준비하는 데 시간이 걸리더라도, 적절하게 컴포넌트를 분리하고 Suspense를 적용하면 페이지의 공통 레이아웃이나 로딩 화면을 먼저 보여줄 수 있습니다.
다만 여기서도 정확하게 구분해야 할 부분이 있습니다.
await를 사용한다고 해서 모든 페이지가 자동으로 빨라지거나 스트리밍이 적용되는 것은 아닙니다. 실제로 어느 부분을 먼저 렌더링할 수 있는지는 컴포넌트의 구성과 데이터 의존성, Suspense 등의 적용 방식에 따라 달라집니다.
또한 기존 Next.js에서도 비동기 처리와 스트리밍은 가능했습니다. Next.js 15에서 이러한 기능이 처음 도입된 것이 아니라, 요청 관련 API를 비동기 형태로 변경함으로써 렌더링을 더욱 유연하게 구성할 수 있는 기반을 확장한 것으로 이해하시는 것이 정확합니다.
다시 처음 질문으로 돌아가 보겠습니다.
제가 강의에서 동기 방식을 '편지를 바로 꺼내는 것', 비동기 방식을 '우체부가 올 때까지 기다리는 것'이라고 설명한 부분은 엄밀히 말하면 동기와 비동기의 일반적인 차이를 올바르게 표현한 비유가 아닙니다.
편지를 바로 꺼낼 수 있다는 것은 단순히 필요한 값이 이미 준비되어 있다는 의미에 가깝습니다. 반대로 우체부를 기다려야 한다는 사실만으로 비동기 방식이라고 판단할 수도 없습니다.
좀 더 적절한 비유를 사용한다면 식당에서 요리하는 상황을 떠올려 볼 수 있습니다.
셰프가 오븐에 음식을 넣고 조리가 끝날 때까지 아무것도 하지 않은 채 기다린다면, 기다리는 동안 다른 일을 진행하지 못하는 상황입니다.
반면 오븐에서 음식이 익는 동안 다른 요리의 재료를 준비하거나 접시를 세팅할 수 있다면, 기다리는 시간을 다른 작업에 활용하는 상황입니다.
물론 마지막에 오븐에서 나온 음식이 필요하다면, 그 시점에는 조리가 끝날 때까지 기다려야 합니다.
비동기 처리도 이와 비슷합니다. 시간이 걸리는 작업이 진행되는 동안 다른 작업을 수행할 수 있지만, 그 결과를 반드시 사용해야 하는 순간에는 완료를 기다릴 수 있습니다.
이러한 관점에서 보면 await로 기다린다는 사실이 비동기 처리와 모순되는 것은 아니라는 점도 자연스럽게 이해하실 수 있을 것입니다.
정리하자면, 동기와 비동기는 작업의 완료와 실행 흐름 사이의 관계를 설명하는 개념이고, async와 await는 JavaScript에서 Promise를 이용한 비동기 작업을 다루기 위한 문법입니다.
그리고 Next.js 15에서 searchParams가 Promise로 변경되었다는 것은 기존의 일반 객체 접근 방식에서 비동기 API를 통해 값을 가져오는 방식으로 변경되었다는 의미이지, 동기와 비동기의 기본적인 개념 자체가 달라졌다는 뜻은 아닙니다.
따라서 강의에서 설명한 Next.js 15의 기술적 변경 사항 자체는 맞지만, 이를 설명하는 과정에서 동기와 비동기의 일반적인 개념을 지나치게 단순화했고, 서로 다른 개념을 충분히 구분하지 못한 부분이 있었습니다.
이 점은 제가 좀 더 정확하고 이해하기 쉽게 설명드렸어야 했는데, 혼동을 드린 점 다시 한번 죄송하다는 말씀을 드립니다.
아울러 질문해 주신 덕분에 강의의 해당 설명을 다시 검토하고, 보완이 필요한 부분도 확인할 수 있었습니다. 해당 구간은 다른 분들도 혼동하지 않으시도록 정정 안내를 보완하겠습니다.
무엇보다 단순히 강의 내용을 그대로 받아들이기보다는, 기존에 알고 계셨던 개념과 비교하고 의문이 생기는 부분을 직접 확인해 주신 점이 인상적이었습니다. 개발을 공부하실 때도 이러한 방식으로 개념을 하나씩 검증하며 이해하는 과정이 큰 도움이 될 것이라고 생각합니다.
다시 한번 좋은 질문 남겨주셔서 진심으로 감사드립니다.
앞으로도 강의를 수강하시면서 이해가 되지 않거나 설명이 어색하게 느껴지는 부분이 있다면 언제든 편하게 질문 남겨주세요. 최대한 자세하고 정확하게 설명드리겠습니다.
감사합니다! 😊
0
안녕하세요, 인프런 AI 인턴입니다. haseung님.
동기와 비동기 개념이 반대로 설명된 것처럼 느껴지셨다면, 아래 기존 답변이 관련 내용을 이해하는 데 도움이 될 수 있습니다.
call stack 표현이 잘못표현된것이 아닌가요?
동기 처리는 앞선 작업이 끝날 때까지 다음 작업이 진행되지 않고 순서대로 실행되는 방식입니다. 반면 비동기 처리는 시간이 걸리는 작업을 시작한 뒤 결과를 기다리지 않고 다음 코드를 실행하며, 작업이 완료되면 콜백·Promise·이벤트 등을 통해 후속 처리를 진행합니다.
예를 들어 다음 코드에서 console.log("D")는 동기 코드이므로 비동기 작업을 등록한 직후에도 먼저 실행됩니다.
setTimeout(() => {
console.log("A");
}, 0);
Promise.resolve().then(() => {
console.log("B");
});
console.log("D");
일반적인 출력 순서는 다음과 같습니다.
D
B
A
setTimeout과 Promise 자체가 호출된 순간 바로 실행되는 것이 아니라, 각각 작업 큐에 등록됩니다. 현재 실행 중인 동기 코드가 모두 끝난 뒤, Promise의 후속 작업인 마이크로태스크가 먼저 실행되고 이후 타이머 콜백이 실행됩니다.
따라서 핵심은 다음과 같습니다.
- 동기: 현재 작업이 끝날 때까지 다음 작업이 기다림
- 비동기: 작업을 시작한 뒤 결과를 기다리지 않고 다음 작업을 진행함
- 비동기라고 해서 먼저 실행되는 것은 아님: 동기 코드가 모두 끝난 후 정해진 우선순위에 따라 실행됨
- Next.js에서도 동일함: 서버 컴포넌트의 데이터 fetching 등은 비동기로 처리할 수 있지만, 해당
await를 만난 코드의 흐름에서는 결과를 기다린 후 다음 줄이 실행됩니다
강의의 어느 문장이나 예시가 반대로 느껴졌는지 코드 또는 강의 화면을 함께 남겨주시면 더 정확히 확인할 수 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
56강 프로젝트 초기화 커밋 시 main이 아니라 master라는 칩이 붙습니다.
0
3
1
awesome mcp
0
17
1
강의할때 문서? 텍스트 있는거 어디서 받아요?
0
16
1
VSCODE Extension Claude와 터미널 차이
0
24
0
claude-nextjs-starterkit에서 .claude폴더 생성
0
24
1
Claude Code 자동 Update 활성화 방법은?
0
17
1
사이트 로그인이 안됩니다
1
20
1
Vercel 배포 과정에서 오류가 발생합니다
0
31
1
Part2 수강 방법
0
35
1
20강 4분 30초 코드와 6분 30초 코드 관련 질문
0
34
1
리프레시토큰
0
40
1
영상에서 소개되는 코드와 강의 노트 코드가 달라요
0
43
1
/memory를 쓸 필요가 있나요? 그냥 md 들어가서 편집하면 안되나용?
0
62
2
오디오 문제
0
54
2
https 도메인
0
47
1
로그인 확인
0
65
3
서브에이전트 생성시 레퍼런스 및 스킬 생성
0
58
2
Git, Github 기초부터 실전까지 중 질문드립니다.
0
80
3
재생이 안됩니다.
0
60
1
TTL 산정 기준
0
46
1
클로드 설치 및 강의 미션 관련
0
66
1
/config Thinking mode 설정
0
59
2
안녕하세요, 강의 수강 중인 학생입니다.
0
54
2
Vercel 사용법
0
250
2





