티스토리 뷰
반응형
Future.microtask()는 Dart에서 비동기 작업을 "가능한 한 빨리" 실행하도록 예약할 때 사용하는 방법이야. 일반적인 Future()나 Future.delayed()와는 조금 다른 용도로 사용돼.
Future.microtask()란?
- microtask queue에 작업을 추가해,
- 현재 실행 중인 코드가 모두 완료되면 (즉, 이벤트 루프의 다음 단계로 넘어가기 전에),
- 가장 먼저 실행되게 만드는 거야.
Future.microtask(() {
print("나는 microtask!");
});
microtask queue vs event queue
구분 설명
microtask queue | 매우 빠르게 실행됨. 현재 작업이 끝나자마자 바로 실행. |
event queue | 예: Timer, I/O, 사용자 입력 등. 이벤트 루프가 한 사이클 돌고 나서 실행됨. |
예를 들어:
print('A');
Future.microtask(() => print('B'));
Future(() => print('C'));
print('D');
출력 결과는:
A
D
B
C
- print('A') → 즉시 실행
- print('D') → 즉시 실행
- print('B') → microtask이므로 D 다음에 실행
- print('C') → 일반 Future이므로 microtask보다 나중에 실행
언제 쓰면 좋을까?
- 빌드 이후에 무언가 실행하고 싶을 때 (예: initState에서는 context 접근이 불안정할 때)
- 프레임워크의 초기 작업들이 끝난 직후에 실행하고 싶을 때
- 다른 비동기 작업보다 우선 실행하고 싶을 때
microtask 사용 예
@override
void initState() {
super.initState();
Future.microtask(() {
if (mounted) {
context.read<ItemProvider>().loadItemStatusCountsByGroup();
}
});
}
위 코드는 위젯이 완전히 마운트된 이후, 최대한 빠르게 loadItemStatusCountsByGroup()를 실행하고 싶은 거야.
- initState()나 didChangeDependencies() 내에서 context 관련 작업을 안전하게 실행하려고 할 때 자주 사용됨.
- setState()를 호출하기에 안전한 시점이기도 해.
Dart 비동기 처리의 기본 구조
Dart는 싱글 쓰레드 기반이지만 비동기 처리를 위해 이벤트 루프(Event Loop) 와 두 가지 큐(queue)를 사용해.
1. Microtask Queue
- Future.microtask()나 scheduleMicrotask()로 추가됨
- 우선순위가 높음 – 현재 코드 실행이 끝나면 바로 실행됨
- 이벤트 큐보다 먼저 실행됨
2. Event Queue
- Future(), Timer, I/O, 사용자 입력 등으로 추가됨
- microtask가 다 처리된 후 실행됨
예시로 이해하기
import 'dart:async';
void main() {
print('A');
Future(() => print('B')); // Event queue
Future.microtask(() => print('C')); // Microtask queue
scheduleMicrotask(() => print('D')); // Microtask queue
Future(() => print('E')); // Event queue
print('F');
}
출력 순서
A
F
C // microtask
D // microtask
B // event queue
E // event queue
왜 microtask를 써야 할까?
주 용도 1: 위젯 라이프사이클 중 안전한 타이밍
initState() 안에서 context.read() 또는 setState() 호출은 조심해야 해. 이럴 땐 microtask로 밀어서 다음 프레임에서 실행되도록 해줘.
@override
void initState() {
super.initState();
Future.microtask(() {
if (mounted) {
context.read<SomeProvider>().fetchData();
}
});
}
주 용도 2: 비동기 로직의 정확한 순서 제어
void main() {
Future(() => print('Event'));
Future.microtask(() => print('Microtask'));
}
→ 결과는 항상 Microtask가 먼저야.
주의할 점
- 무한 루프 조심: microtask 안에서 또다시 microtask를 예약하면 빠져나올 수 없어.
- 너무 남발 금지: 모든 비동기를 microtask로 만들면 CPU를 독점할 수도 있음.
요약
비교 대상 Future.microtask Future()
위치 | microtask queue | event queue |
실행 시점 | 현재 코드 끝난 후 즉시 | 다음 이벤트 루프 주기 |
우선순위 | 높음 | 낮음 |
사용 예 | 위젯 초기화 이후 실행, 빠른 처리 필요할 때 | 일반 비동기 로직 처리 |
반응형
댓글
공지사항