1. 비동기 프로그래밍 살펴보기
아래의 코드 스니펫(원본 소스코드의 일부)는 버튼이 눌렸을 때 콘솔에 '버튼이 눌렸습니다!'라는 메시지를 출력하는 기능이 구현되어 있습니다.
ElevatedButton(
onPressed: () {
print('버튼이 눌렸습니다!');
},
child: Text('눌러보세요'),
)
이 버튼을 눌렀을 때, 만약 시간이 오래 걸리는 작업(예: 서버에서 데이터 가져오기, 파일 읽기 등)을 해야 한다면, 이 작업이 끝날 때까지 앱이 멈추지 않고, 다른 작업을 동시에 할 수 있게 만드는 것이 비동기 프로그래밍의 핵심입니다.
2. 비동기 프로그래밍이 필요한 이유
만약 버튼을 눌렀을 때 서버에서 데이터를 가져오는 작업이 포함되어 있다고 가정해봅시다. 이 작업은 몇 초가 걸릴 수도 있습니다. 비동기 프로그래밍을 사용하지 않으면, 이 작업이 완료될 때까지 앱이 멈춰서 아무런 응답을 하지 않게 됩니다. 이는 사용자 경험을 크게 저하시킵니다.
2-1. 사용자 경험(User Experience)이란 ?
여기서 사용자 경험이란 사용자가 제품이나 서비스를 사용할 때 느끼는 전반적인 경험을 말합니다. UX는 사용자의 편의성, 효율성, 만족도 등 다양한 요소를 고려하여, 제품이 얼마나 사용하기 쉽고, 유용하며, 즐거운지 평가합니다. 좋은 UX는 사용자가 제품을 쉽게 이해하고, 목표를 효과적으로 달성하며, 긍정적인 감정을 느끼도록 돕는 것을 목표로 합니다.
3. 비동기 프로그래밍 적용
이제 주어진 코드에 비동기 프로그래밍을 적용해 보겠습니다. 예를 들어, 버튼을 눌렀을 때 서버에서 데이터를 가져오는 작업을 비동기로 처리하도록 코드를 수정합니다. 데이터를 서버에 요청했을 때, 통신 지연 시간(Latency), 연산 지연 시간(Processing delay)으로 인해 요청한 데이터를 수신하기까지 3초의 지연시간이 발생하였다고 가정하겠습니다.
이전 3화에서 진행했던 코드에 버튼을 추가해보겠습니다.
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Hello, world!',
textDirection: TextDirection.ltr,
style: TextStyle(fontSize: 24, color: Colors.blue),
),
ElevatedButton(
onPressed: () async {
print('버튼이 눌렸습니다! 데이터 가져오는 중...');
// 비동기 작업: 데이터를 가져오는 함수 호출
String data = await fetchDataFromServer();
print('데이터가 도착했습니다: $data');
},
child: Text('눌러보세요'),
),
],
),
),
),
);
}
// 서버에서 데이터를 가져오는 비동기 함수
Future<String> fetchDataFromServer() async {
await Future.delayed(Duration(seconds: 3)); // 3초 대기
return '서버에서 받은 데이터';
}
3-1. 실행 결과 살펴보기
실행하게 되면 "Hello, world!" 라는 문구와 함께 "눌러보세요"라는 문구가 들어있는 버튼 하나가 표시됩니다. 버튼 동작을 확인하기위해 개발자 도구에서 Console 탭을 선택합니다. 개발자 도구는 크롬 환경에서 F12 버튼으로 실행가능합니다.
버튼을 클릭하게 되면 "버튼이 눌렸습니다! 데이터 가져오는 중..." 라는 문구가 콘솔에 출력됩니다.
3초가 지나면 "데이터가 도착했습니다: 서버에서 받은 데이터" 라는 문구가 콘솔에 발생합니다.
3-2. 코드 이해하기
async와 await
onPressed 콜백 함수 앞에 async 키워드를 붙여, 이 함수가 비동기적으로 실행될 수 있게 합니다.
await 키워드를 사용하여 fetchDataFromServer() 함수가 완료될 때까지 기다립니다. 하지만 이 기다림 동안에도 앱은 다른 작업(예: UI 업데이트)을 계속할 수 있습니다.
fetchDataFromServer() 함수
이 함수는 Future<String>을 반환하는 비동기 함수입니다.
내부에서 Future.delayed(Duration(seconds: 3))를 사용하여 3초간 대기한 후, 데이터를 반환합니다. 이 대기는 서버에서 데이터를 가져오는 데 걸리는 시간을 시뮬레이션한 것입니다.
비동기 작업의 처리
버튼을 누르면 먼저 "데이터 가져오는 중..." 메시지를 출력합니다.
fetchDataFromServer()가 완료되면 데이터가 도착했다는 메시지를 출력합니다.
4. 비동기 프로그래밍의 중요성 체감하기
3번에서 진행한 비동기 프로그래밍 예제로는 비동기 프로그래밍의 장점을 체감하기 어렵습니다. 그렇기에 이번 예제는 비동기 프로그래밍의 중요성을 한번 느껴보겠습니다.
4-1. 예제 코드를 실행해봅시다.
아래는 이전과 달리 버튼이 총 4개 존재하는 예제입니다. 주어진 코드를 실행해보도록 하겠습니다.
import 'package:flutter/material.dart';
void main() {
runApp(
MaterialApp(
home: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Hello, world!',
textDirection: TextDirection.ltr,
style: TextStyle(fontSize: 24, color: Colors.blue),
),
ElevatedButton(
onPressed: () async {
print('버튼 1이 눌렸습니다! 데이터 가져오는 중...');
// 비동기 작업: 데이터를 가져오는 함수 호출
String data = await fetchDataFromServer();
print('버튼 1의 데이터가 도착했습니다: $data');
},
child: Text('버튼 1'),
),
ElevatedButton(
onPressed: () async {
print('버튼 2가 눌렸습니다! 데이터 가져오는 중...');
// 비동기 작업: 데이터를 가져오는 함수 호출
String data = await fetchDataFromServer();
print('버튼 2의 데이터가 도착했습니다: $data');
},
child: Text('버튼 2'),
),
ElevatedButton(
onPressed: () async {
print('버튼 3이 눌렸습니다! 데이터 가져오는 중...');
// 비동기 작업: 데이터를 가져오는 함수 호출
String data = await fetchDataFromServer();
print('버튼 3의 데이터가 도착했습니다: $data');
},
child: Text('버튼 3'),
),
ElevatedButton(
onPressed: () async {
print('버튼 4가 눌렸습니다! 데이터 가져오는 중...');
// 비동기 작업: 데이터를 가져오는 함수 호출
String data = await fetchDataFromServer();
print('버튼 4의 데이터가 도착했습니다: $data');
},
child: Text('버튼 4'),
),
],
),
),
),
);
}
// 서버에서 데이터를 가져오는 비동기 함수
Future<String> fetchDataFromServer() async {
await Future.delayed(Duration(seconds: 3)); // 3초 대기
return '서버에서 받은 데이터';
}
4-2. 실행 결과
총 4개의 귀여운 버튼이 생겼습니다. 빠르게 차례대로 4개의 버튼을 눌러보겠습니다.
이전 3번에서 살펴본 예제처럼 "버튼이 눌렸습니다! 데이터 가져오는 중..." 이라는 문구가 발생합니다. 하지만 이 문구가 연달아서 4개가 발생하고, 이후에 4개가 데이터가 도착하였다는 문구가 연속적으로 발생하는 것을 볼 수 있습니다.
분명히 버튼 1번을 누른 뒤에 버튼 2번을 눌렀음에도 불구하고, 버튼 1번의 작업인 서버에 데이터 요청하기가 끝나지 않았음에도 버튼 2번의 작업이 시작된 것입니다. 이것이 바로 비동기 프로그래밍의 장점입니다. 긴 작업이 실행되는 동안에도 프로그램이 멈추지 않고, 다른 작업(예: 사용자 입력 처리, UI 업데이트 등)을 계속 수행할 수 있습니다.
5. 비동기 프로그래밍의 장단점
비동기 프로그래밍의 장단점을 정리하고 이번 포스트를 마치겠습니다.
5-1. 장점
높은 응답성
긴 작업이 실행되는 동안에도 프로그램이 멈추지 않고, 다른 작업(예: 사용자 입력 처리, UI 업데이트 등)을 계속 수행할 수 있습니다. 이는 사용자 경험을 크게 개선할 수 있습니다.
자원 효율성
시간이 오래 걸리는 작업을 처리하는 동안 CPU 자원을 다른 작업에 사용할 수 있어 자원을 효율적으로 활용할 수 있습니다.
여러 작업을 동시에 처리할 수 있어, 전체적인 처리 시간이 단축될 수 있습니다.
비동기 네트워킹
네트워크 요청과 같은 I/O 작업에서 비동기 프로그래밍이 매우 유용합니다. 네트워크 요청이 완료될 때까지 기다리지 않고, 다른 작업을 처리할 수 있습니다.
5-2. 단점
복잡성 증가
코드가 더 복잡해질 수 있으며, 특히 비동기 작업의 순서를 관리하는 것이 어려울 수 있습니다. 콜백 지옥이나 비동기 코드의 흐름을 관리하기 위한 추가적인 코드가 필요할 수 있습니다.
비동기 작업 사이의 의존 관계나 오류 처리를 관리하는 것이 복잡할 수 있습니다.
디버깅 어려움
비동기 코드에서 문제가 발생했을 때, 문제의 원인을 추적하고 디버깅하는 것이 동기식 코드보다 더 어렵습니다. 특히, 비동기 작업이 여러 단계로 나누어져 있을 때 문제가 될 수 있습니다.
오류 처리
비동기 작업의 오류를 처리하는 것은 종종 복잡하며, 특히 여러 작업이 동시에 수행될 때는 각 작업의 오류를 별도로 관리해야 합니다.
'웹 · 앱 개발 > 플러터(Flutter)' 카테고리의 다른 글
Flutter 5화 - 상태(State) (0) | 2024.08.17 |
---|---|
Flutter 3화 - UI 기초(클래스, 객체, 속성, Text) (0) | 2024.08.10 |
Flutter 2화 - Dart 문법 학습하기 (0) | 2024.08.10 |
Flutter 1화 - Flutter 설치 및 예제 (0) | 2024.08.10 |