JavaScript의 이벤트 루프를 이해하는 것은
특히 React의 컨텍스트에서 효율적이고
반응성이 뛰어난 애플리케이션
을 작성하는 데 매우 중요
📰 알아보기
이벤트 루프가 어떻게 작동하는지 분석한 다음
React 구성 요소 이벤트 처리 시나리오와 연결
호출 스택
@ LIFO(Last In, First Out) 구조
@ JavaScript 가 함수 호출(실행 컨텍스트)을 추적
* 스택에 푸시되는 마지막 함수가 실행이 완료되면 가장 먼저 팝오프
콜백 대기열 (큐)
@ 비동기 이벤트가 발생하면 해당 콜백이 작업 큐(또는 콜백 큐)로 푸시
(예: setTimeout 과 AJAX 호출 또는 사용자 이벤트)
@ 콜백은 호출 스택이 비어 있을 때까지
(즉, 현재 실행 중인 모든 스크립트가 완료될 때까지) 큐에서 대기
@ 이벤트 루프
console.log('Start'); // 1st: call stack 에서 즉시 처리
setTimeout(() => {
console.log('Inside setTimeout'); // 3rd: callback queue 에서 지연 후 실행
}, 0);
console.log('End'); // 2nd: 'Start' 이후 callstack 에 push 되며 실행
@ React 컴포넌트 이벤트 처리 및 이벤트 루프
React 에서 이벤트는 네이티브 브라우저 이벤트에 대한
브라우저 간 인터페이스 제공하는 SyntheticEvent 를 통해 관리
import React, { useState } from 'react';
function MyComponent() {
const [clickCount, setClickCount] = useState(0);
const handleClick = () => {
// 비동기 작업 (setTimeout 으로 시뮬레이션)
setTimeout(() => {
setClickCount(clickCount + 1);
console.log('Clicked', clickCount + 1, 'times');
}, 1000);
};
return <button onClick={handleClick}>Click me</button>;
}
handleClick
단추를 클릭하면 호출handleClick
내에는 setTimeout
이 존재, 해당 함수는 비동기handleClick
함수 포함)setTimeout
으로 Callback 을 호출 스택으로 전송상태 업데이트가 일괄처리
때문에 보다 효율적인 렌더링 가능@ React 에서 이벤트 루프 활용 및 최적화
@ Promises 와 Async-Await 이용한 이벤트 루프
Promises
Async-Await
function fetchData() {
return new Promise(resolve => {
setTimeout(() => resolve('Data fetched'), 1000);
});
}
function processData() {
console.log('Start processing (inside promise)'); // 2nd
return fetchData() // 3rd
.then((data) => {
// 5th 1초뒤 data 로그
console.log(data);
// 6th
console.log('Data processed (inside promise)');
});
}
console.log('Before calling processData'); // 1st
processData()
.then(() => {
// 7th
console.log('After processData is resolved');
});
console.log('After calling processData'); // 4th
Before calling processData
Start processing (inside promise)
After calling processData
Data fetched
Data processed (inside promise)
After processData is resolved
function fetchData() {
return new Promise(resolve => {
setTimeout(() => resolve('Data fetched'), 1000);
});
}
async function processData() {
console.log('Start processing'); // 2nd: 즉시 실행
const data = await fetchData(); // 3rd: Promise 해결될 때까지 대기
console.log(data); // 5th: Promise 해결된 후 실행
console.log('End processing'); // 6th: Follows after the above console.log
}
console.log('Before processing'); // 1st: 즉시 실행
processData();
// 4th: processData 비동기 실행 이전에 외부 동기 코드 실행
console.log('After processing');
Before processing
Start processing
After processing
Data fetched
End processing
* JavaScript에서 함수 내에서 async-await 사용할 때
- 해당 함수의 실행은 비동기 작업의 키워드에서 일시 중지
- JavaScript 런타임은 해당 함수 외부의 다른 동기 코드를 계속 실행
- 비동기 작업이 해결되면 함수 내의 실행이 동기식인 것처럼 다시 시작