You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
functionfoo(){lettodos;constget=(url)=>{constxhr=newXMLHttpRequest();xhr.open('GET',url);xhr.send();xhr.onload=()=>{if(xhr.status===200){**console.log("A: 비동기 콜백 (함수 내부)");**}else{console.error();}}}get('url');console.log(todos);// undefined**console.log("B: 함수 내부 동기 코드");**}foo();// foo 함수 호출**console.log("C: 함수 외부 동기 코드");**
console.log(todos); // undefined ← 콜 스택에 푸시
****console.log("B: 함수 내부 동기 코드"); ← 콜 스택에 푸시
이때,
get 함수가 종료되기 전
get 함수가 종료된 후 console.log()가 실행되고 있을 때
이 시점에 서버로부터의 응답이 도착할 수도 있음. 응답이 도착하는 즉시 브라우저의 Web API는 onload 콜백 함수를 태스크 큐에 등록함.
하지만 아직 example 함수 내부에 실행되지 않은 동기 코드들이 남아있고, 함수 내부에서 콜스택에 들어갈 수 있는 동기 코드가 남아있을 때는 task queue에 등록된 비동기 함수들은 절대로 먼저 콜스택에 들어갈 수 없으므로 → load 함수의 콜백함수는 무조건 모든 console.log()들이 다 실행돼 콜 스택에서 pop됐을 때 이벤트 루프에 의해 콜 스택에 등록돼 실행됨
Q:foo 함수가 끝난 후, 그 뒤에 있는 "외부 동기 코드"보다 foo 함수에 의해 태스크 큐에 등록된 비동기 함수가 먼저 처리될까? A: 외부 동기 코드가 항상 먼저 실행됨.
이벤트 루프는 특정 함수의 종료 여부가 아닌, 전역 스코프를 포함한 현재 실행 중인 모든 동기 코드가 완료되기를 기다림. 함수 스코프는 중요하지 않다!
이벤트 루프는 C까지 모두 실행되어 콜 스택이 완전히 비워진 후에야 태스크 큐에 있는 A를 처리함
Q2.
동기 코드부터 먼저 실행
각 매크로태스크 후에 마이크로태스크 큐를 전부 비운다
Promise 체인은 순서대로 연결된다
console.log(시작) 실행 → ‘시작’ 출력
setTimeout(..., 0) 만남
setTimeout 호출 → 콜백이 Web API의 타이머에 등록됨
타이머 만료 시 태스크 큐로 이동
콜 스택이 비었을 때 이벤트 루프에 의해 콜 스택으로 이동해 콜백 실행
⇒ 여기서는 타이머가 0초로 세팅됐으므로 콜백이 Web API에 등록되자마자 바로 매크로태스크 큐로 이동
Promise.resolve()... 만남
.then({ C ... }) 메서드의 콜백 함수는 즉시 실행되지 않고, 마이크로태스크 큐에 등록됨
try{setTimeout(()=>{thrownewError('Error!');},1000);// <- try 블록 끝남}catch(e){// 여기는 이미 끝났음}
try 블록 진입
setTimeout 호출 (콜백만 등록)
try 블록 완전히 끝남
catch 블록도 끝남
1초 경과
콜백 실행 → 에러 발생 → 하지만 try-catch는 이미 끝났으므로 처리 안 됨
try-catch 실행 컨텍스트가 이미 종료된 상태에서 콜백이 실행되기 때문에, 에러가 발생해도 처리할 catch 블록이 없다!
async/await
asyncfunctiontest(){try{constresult=awaitpromise~~;// <- 여기서 대기console.log(result);}catch(e){console.error(e);// 에러 정상 처리}}
async 함수 실행 시작
try 블록 진입
await promise 만남 → await 키워드는 프로미스가 settled 상태(비동기 처리가 수행된 상태)가 될 때까지 대기하다가 settled 상태가 되면 프로미스의 결과를 반환함
→ try 블록은 여전히 활성 상태
Promise가 reject됨
await가 그 에러를 받음 → 같은 실행 컨텍스트에서 catch 블록으로 이동
catch 블록 실행 → 에러 처리됨
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Q1. 비동기 함수와 콜백
Q: 위 코드의 실행 결과는?
Q2. 비동기 함수와 태스크 큐
Q: 이 코드의 실행 순서는?
Q3. async/await
Q: 콜백을 인수로 받는 비동기 함수는 try-catch로 에러 처리가 불가능한데, async/await는 왜 가능한가요?