1. dart 비동기 프로그래밍에 대한 개념
2. flutter 타입에 이해
3. Future 타임과 Future delayed 함수 사용해 보기
1. dart 비동기 프로그래밍에 대한 개념을 이해하자.
동기성 - 모든 코드가 순차적으로 진행되는 형태, 재 작업이 끝날 때까지 프로그램은 다음 작업을 시작하지 않습니다.
예를 들어, 파일 읽기 작업이 끝나야만 다음 줄의 코드가 실행됩니다.
비동기 - 코드가 동시다발적으로 실행, 순착적으로 보장을 할 수 없는 형태
dart 비동기 프로그래밍은 프로그램의 흐름을 중단시키지 않고, 무언가의 완료를 기다리는 동안 다른 작업을 수행할 수 있게 해줍니다. Dart에서는 이를 위해 Future라는 데이터 타입을 제공 합니다.
* 자바에서 비동기 처리
키워드
async / await / Future : 1회만 응답을 돌려 받는 경우
Future 타입이 뭘까?
Future 객체는 미래에 어떤 값이나 오류를 반환할 것이라는 약속을 나타냅니다. async 키워드가 붙은 함수 내부에서 await 키워드를 사용하면, Future가 완료될 때까지 실행을 잠시 멈추고 결과가 준비되면 다시 실행을 계속합니다
동기식
시나리오 코드1 - Future 타입 사용해보기 => 동기식이라면?
void main() {
print('task1........1');
var data1 = fetchData();
print('data1 ${data1}');
print('task1........2');
fetchData();
print('task1........3');
}
Future<String> fetchData() {
return Future.delayed(
Duration(seconds: 3),
() {
return '3초 동안 기다렸어';
},
);
}
결과
task1........1
data1 Instance of 'Future<String>'
task1........2
task1........3
비동기 처리시
시나리오 코드2 - Future 타입 사용해보기 => 비동기식
// async / await 는 비동기 처리를 마치 동기적 방식으로 코드를 만들어 준다.
void main() async {
// 비동기 프로그래밍 테스트 코드
// 동기성 - 모든 코드가 순차적으로 진행되는 형태
// 비동기성 - 코드가 동시 다발적으로 실행, 순차적 실행을 보장 할 수 없다.
// 키워드 묶음
// async / await --> Future : 1회만 응답을 돌려 받는 경우 사용한다.
// 규칙 - 함수 내부에서 await 키워드를 가지고 있다면 그 함수를 감싸는 블록은
// 무조건 async 키워드를 붙여야 한다 (왜 컴파일러가 비동기 코드 있다고 알아야 한다.)
print('task 1 ...........');
var data1 = await fetchData();
print('task 2 ...........');
print('task 3 ...........');
print('data1 확인 : ${data1}');
}
Future<String> fetchData() {
return Future.delayed(
Duration(seconds: 3),
() {
return '3초동 기다렸어!!!';
},
);
}
결과
task1........1
data1 3초 동안 기다렸어
task1........2
task1........3
첫 번째 코드
void main() {
print('main 함수 시작');
mutliple(2, 3);
print('main 함수 종료');
}
Future<void> mutliple(int n1, int n2) async {
int result = 0;
await Future.delayed(Duration(seconds: 5), () => result = n1 * n2);
print('결과값 : ${result}');
}
Futur 메소드 안에서 awit, asyn 만 처리 해줬을때는 , 아래의 결과와 같이 순차적으로 발생하지 않지만, 일단 결과값은 나오는 상태가 됨
main 함수 시작
main 함수 종료
결과값 : 6
하지만 main 함수 자체에서 async, await를 처리해 준다면 ?
두 번째 코드
void main() async{
print('main 함수 시작');
await mutliple(2, 3);
print('main 함수 종료');
}
Future<void> mutliple(int n1, int n2) async {
int result = 0;
await Future.delayed(Duration(seconds: 5), () => result = n1 * n2);
print('결과값 : ${result}');
}
main 함수 시작
결과값 : 6
main 함수 종료
함수가 순차적으로 발생하는 것을 확인할 수 있다.
그 이유는 무엇일까?
1. async와 await의 역할
- async 키워드는 함수가 비동기 함수임을 선언하며, 이 함수는 항상 Future를 반환합니다.
- await 키워드는 비동기 연산의 완료를 기다리는 역할을 합니다. 즉, 해당 비동기 작업이 완료될 때까지 함수 실행이 중단됩니다.
2. 첫 번째 코드: main 함수에서 async/await를 사용하지 않음
- main 함수는 동기 함수로 실행됩니다. 따라서 mutliple(2, 3)을 호출한 후 즉시 다음 코드로 진행합니다.
- mutliple 함수 내에서 await는 비동기 작업(Future.delayed)을 기다리지만, main 함수는 mutliple 함수의 완료를 기다리지 않고 자체 흐름을 계속 진행합니다.
- 결과적으로, 출력 순서는 다음과 같습니다:
- main 함수 시작
- main 함수 종료
- (5초 후) 결과값 : 6
3. 두 번째 코드: main 함수에서 async/await 사용
- main 함수가 비동기 함수(async)로 선언되었으며, await를 사용하여 mutliple(2, 3)의 완료를 기다립니다.
- main 함수는 mutliple 함수가 완료될 때까지 실행을 중단합니다.
- 따라서 출력 순서는 다음과 같습니다:
- main 함수 시작
- (5초 후) 결과값 : 6
- main 함수 종료
4. 왜 await가 순차 실행을 보장할까?
- await는 현재 함수의 비동기 작업이 완료될 때까지 기다리는 역할을 합니다.
- await는 현재 스레드의 실행을 차단하지 않고, Dart의 Event Loop를 통해 다른 작업을 계속 처리할 수 있게 합니다.
- 하지만 await가 사용된 함수 자체의 흐름은 해당 비동기 작업이 완료되기 전까지 정지합니다.
5. 비동기 작업의 흐름 요약
- main 함수에서 async/await를 사용하지 않은 경우:
- main 함수는 비동기 작업의 완료 여부와 상관없이 즉시 다음 코드로 진행합니다.
- 비동기 작업은 별도의 Future 체인에서 실행되고, 완료 후 결과를 출력합니다.
- main 함수에서 async/await를 사용한 경우:
- main 함수는 비동기 작업의 완료를 기다립니다.
- 비동기 작업이 완료된 후에야 다음 코드로 진행합니다.
- async/await를 사용하면 동기식 코드처럼 비동기 작업을 순차적으로 작성할 수 있습니다.
- await는 함수 내 흐름을 중단하여 비동기 작업의 결과를 기다리지만, Dart의 Event Loop는 다른 작업을 처리할 수 있으므로 전체 프로그램이 차단되지는 않습니다.
시나리오코드 4 - async await 사용
void main() async {
print('메인함수 시작 ');
// var result2 = addNumber1(1, 2);
// print('addnumber1 결과 : ${result2}');
await addNumber2(2, 5);
print('메인함수 종료');
}
//
// Future<int> addNumber1(int n1, int n2) async {
// print('addNumber1 함수 시작');
// var result = 0;
// await Future.delayed(Duration(seconds: 3), () {
// result = n1 + n2;
// });
// print('addNumber1 연산 완료 : ${result}');
//
// //return result;
// return Future.value(result);
// }
//await가 없다면 문제가됨
Future<void> addNumber2(int n1, int n2) async {
print('addNumber1 함수 시작');
var result = 0;
await Future.delayed(Duration(seconds: 3), () {
result = n1 + n2;
});
print('addNumber2 연산 완료 : ${result}');
//return result;
}
시나리오코드 4 - then
비동기 방식으로 콜백으로 이벤트 핸들러 처리를 한다.
void main() {
print('메인함수 시작');
//소화1 방식 async / await 방식 사용방법
//소화2 방식 then이다.
addNumber2(10, 5).then(
(value) => print('결과 : ${value}'),
);
print('메인함수 종료');
}
Future<int> addNumber2(int n1, int n2) {
return Future.delayed(Duration(seconds: 3), () => n1 + n2);
}
질문!! , 만약 main에 async를 설정할 경우 다른 동기 타입의 클래스에는 영향이 가지 않을까?
main 함수에 async를 설정하더라도, Future를 반환하지 않는 동기 함수나 클래스에는 전혀 영향을 미치지 않습니다. 이는 Dart의 비동기 처리 방식과 async의 역할 때문입니다.
1. async의 역할
- async는 해당 함수 내에서 비동기 코드를 사용할 수 있게 해주는 선언입니다.
- 함수에 async를 붙이면 함수는 항상 Future를 반환합니다.
- 예: void main() → Future<void> main()
- 그러나 async가 붙은 함수 내부에서 동기 코드는 기존처럼 즉시 실행됩니다.
2. 동기 함수나 클래스는 영향을 받지 않음
Dart는 동기와 비동기 코드를 별도로 처리합니다:
- 동기 코드(synchronous code): 즉시 실행되며, async/await의 영향을 받지 않습니다.
- 비동기 코드(asynchronous code): Future나 Stream을 사용하며, await 키워드로 결과를 기다릴 수 있습니다.
따라서, main 함수에 async를 붙이더라도 동기적인 클래스 생성, 메서드 호출, 변수 초기화 등은 기존처럼 동작합니다.
결론
- async는 해당 함수 내의 비동기 코드의 실행 흐름에만 영향을 미칩니다.
- 동기 함수나 클래스는 async 선언과 상관없이 기존의 즉시 실행 방식으로 동작합니다.
- async/await를 통해 필요한 부분에서만 비동기 작업을 대기하고, 동기 코드는 성능에 영향을 받지 않도록 설계됩니다.
'Flutter' 카테고리의 다른 글
[flutter21] dio (0) | 2025.01.14 |
---|---|
[flutter20] CallBack 함수 (0) | 2025.01.14 |
[flutter 20] shopping_cart_app 만들기 (0) | 2025.01.13 |
댓글