비동기 처리(Asynchronous Processing)란 작업이 완료될 때까지 기다리지 않고, 다음 작업을 진행하는 방식을 의미합니다.
쉽게 말해, 우리가 음식을 주문하고 조리가 끝날 때까지 가만히 기다리는 것이 아니라, 다른 일을 하다가 음식이 나오면 다시 돌아와서 먹는 것과 같은 원리입니다.
Flutter에서는 네트워크 요청, 파일 읽기, 데이터베이스 조회 등 시간이 오래 걸리는 작업을 효율적으로 처리하기 위해 비동기 처리를 사용합니다.
처리 방식 | 설명 | 예시 |
---|---|---|
동기 처리(Synchronous) | 작업이 완료될 때까지 기다린 후 다음 작업을 실행 | 음식을 주문하고 조리가 끝날 때까지 기다리는 것 |
비동기 처리(Asynchronous) | 작업이 끝날 때까지 기다리지 않고, 다음 작업을 진행 | 음식을 주문한 후 다른 일을 하다가 완료되면 먹는 것 |
void main() {
print("1. 데이터를 요청합니다.");
fetchData(); // 시간이 오래 걸리는 작업
print("3. 데이터를 화면에 출력합니다.");
}
void fetchData() {
for (int i = 0; i < 1000000000; i++) {} // 시간이 걸리는 연산
print("2. 데이터 요청 완료!");
}
출력 결과:
1. 데이터를 요청합니다.
2. 데이터 요청 완료!
3. 데이터를 화면에 출력합니다.
위와 같이 fetchData()가 완료될 때까지 다음 코드가 실행되지 않습니다.
void main() async {
print("1. 데이터를 요청합니다.");
await fetchData(); // 비동기 처리
print("3. 데이터를 화면에 출력합니다.");
}
Future<void> fetchData() async {
await Future.delayed(Duration(seconds: 2));
print("2. 데이터 요청 완료!");
}
출력 결과:
1. 데이터를 요청합니다.
(2초 후)
2. 데이터 요청 완료!
3. 데이터를 화면에 출력합니다.
비동기 코드를 사용하면 작업이 끝날 때까지 기다리지 않고 다른 작업을 수행할 수 있습니다.
Flutter에서 비동기 처리는 주로 Future
, async/await
, 그리고 then
을 사용하여 구현합니다.
Future<String> fetchData() {
return Future.delayed(Duration(seconds: 2), () => "데이터 로드 완료");
}
📌 Future는 비동기 작업의 결과를 나타내는 객체입니다.
then
또는 await
을 사용하여 결과를 처리할 수 있습니다.void main() async {
print("데이터를 불러오는 중...");
String data = await fetchData();
print(data);
}
📌 async/await은 Future를 더 직관적으로 사용할 수 있도록 도와줍니다.
async
키워드를 함수에 추가하면 비동기 함수가 됩니다.await
키워드를 사용하면 Future가 완료될 때까지 기다렸다가 실행됩니다.try-catch
블록을 사용하여 오류를 쉽게 처리할 수 있습니다.void main() {
print("데이터를 불러오는 중...");
fetchData().then((data) {
print(data);
});
}
📌 then() 메서드는 Future의 결과를 받아 처리할 때 사용됩니다.
await
을 사용할 수 없는 경우(예: 기존의 콜백 방식) 유용하게 사용됩니다.then
체인이 복잡해지고 가독성이 떨어질 수 있습니다.방식 | 장점 | 단점 |
---|---|---|
Future | 비동기 작업을 실행하고 then 을 사용해 결과 처리 가능 | 여러 개의 then 체인이 생기면 가독성이 떨어짐 |
async/await | 동기 코드처럼 직관적으로 작성 가능, 가독성이 뛰어남 | await 은 async 함수 내에서만 사용 가능 |
then | 콜백 스타일로 비동기 처리 가능, 간단한 작업에 적합 | 중첩되면 코드가 복잡해짐 (콜백 지옥 발생 가능) |
비동기 처리는 다음과 같은 경우에 사용됩니다.
비동기 처리는 사용자의 경험을 부드럽게 만들어주며, UI가 멈추지 않도록 도와줍니다.
비동기 처리는 매우 강력하지만, 모든 코드를 비동기로 작성하면 오히려 불필요한 복잡성이 증가할 수 있습니다.
📌 주의해야 할 점
따라서, 비동기 처리는 필요할 때만 신중하게 사용해야 합니다.
비동기 처리와 관련하여 알아두면 좋은 개념들은 다음과 같습니다.
Future
는 한 번의 작업을 처리하지만, Stream
은 여러 개의 데이터를 순차적으로 처리할 수 있습니다.
Stream<int> countStream() async* {
for (int i = 0; i < 5; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
Flutter는 단일 스레드에서 실행되지만, Isolate를 사용하면 별도의 스레드에서 작업을 실행할 수 있습니다.
import 'dart:isolate';
void backgroundTask(SendPort sendPort) {
sendPort.send("백그라운드 작업 완료!");
}
비동기 처리는 Flutter 개발에서 필수적인 개념으로, 앱의 성능과 사용자 경험을 향상시키는 데 중요한 역할을 합니다.
- 동기 처리와 비동기 처리의 차이를 이해하고, 필요할 때 적절히 사용해야 하며,
- async/await, Future, Stream 등의 개념을 숙지하여 다양한 상황에서 비동기 처리를 활용할 수 있어야 합니다.