
한 번에 하나의 작업만 처리할 수 있다!
-> 따라서 오래 걸리는 작업을 비동기로 실행하면 ui 렌더링이 뒤로 밀린다...
해당 작업이 사용하려던 메인 스레드를 양보한다
-> 해당 작업은 다음 이벤트 루프에서 실행되도록 예약된다.
-> 따라서 작업의 우선순위를 현재 실행 중인 코드가 끝난 후로 미룰 수 있다!
// setTimeout을 사용한 기존 접근 방식
setTimeout(() => {
processNextBatch();
}, 0);
세분화된 제어와 적절한 우선순위 관리 기능 부족
| 작업 종류 | 설명 | 예시 |
|---|---|---|
| user-blocking | 메인 스레드를 차단하고 즉각적인 처리가 필요한 작업 | 사용자 입력 처리, UI 업데이트 |
| user-visible | 중요하지만 user-blocking만큼은 아닌 작업 | 다음 화면을 위한 데이터 가져오기 |
| background | 사용자 경험에 영향을 미치지 않고 백그라운드에서 동작할 수 있는 작업 | 에셋 미리 로드, 분석 수행 |
await scheduler.yield();
processNextBatch();
yield보다 복잡한 상황(우선순위 필요)에서 사용
await scheduler.postTask(() => {
processNextBatch() },
{ priority: 'background' }
);
async function processData(data) {
const controller = new TaskController({ priority: 'background' });
try {
await scheduler.postTask(
() => heavyComputation(data),
{
signal: controller.signal,
priority: 'background'
}
);
} catch (error) {
if (error.name !== 'AbortError') {
console.error('Processing failed:', error);
}
}
controller.abort(); //작업 중단
}
const controller = new TaskController({ priority: 'background' });
//바뀐 경우 감지 가능
controller.signal.addEventListener('prioritychange', (event) => {
console.log(`${event.previousPriority} to ${event.target.priority}`);
});
scheduler.postTask(
async () => {
await processInitialData(); // 백그라운드 작업으로 시작
controller.setPriority('user-visible'); //우선순위 변경
await processCriticalData();
},
{ signal: controller.signal }
);