3.1 동기 vs. 비동기 프로그래밍
동기 : 요청 후 응답을 받을 때까지 대기. 응답을 받은 후 다음 코드를 실행
비동기 : 응답을 대기하지 않으며 응답 순서 또한 요청 순서와 다를 수 있음
3.2 Future
Future 클래스 : 미래에 받아올 값을 뜻함. 제네릭으로 어떤 미래의 값을 받아올지를 정할 수 있다
ex) Future<String> name; //미래에 받을 String값
ex) Future<int> number; //미래에 받을 int값
비동기 프로그래밍에서는 요청 처리가 오래 걸리는 작업을 기다린 후 값을 받아와야 하기 때문에 미래값을 표현하는 Future 클래스를 사용.
void main() {
addNumbers(1,1);
}
void addNumbers(int num1, int num2){
print('계산 시작');
//Future.delayed(): 일정 시간 후에 콜백 함수 실행
Future.delayed(Duration(seconds: 3), (){
print('$num1 + $num2 = ${num1+num2}');
});
print('계산 끝');
}
설정한 Duration동안 대기하라는 메시지를 받으면 cpu는 리소스를 허비하지 않고 다음 코드를 바로 실행하므로, 계산 시작 -> 계산 끝 -> 1+1=3 의 순서로 값이 출력된다.
3.3 async와 await
비동기 프로그래밍을 유지하면서도 코드 가독성을 유지하는 방법
void main() {
addNumbers(1,1);
}
Future<void> addNumbers(int num1, int num2) async {
print('계산 시작');
await Future.delayed(Duration(seconds: 3), (){
print('$num1 + $num2 = ${num1+num2}');
});
print('계산 끝');
}
async는 함수 매개변수 정의와 바디 사이에 입력
await는 대기하고 싶은 비동기함수 앞에 입력
이때는 Future.delayed()의 실행을 기다렸다가 아래 코드를 실행하게 되므로 계산 시작->1+1=2->계산 끝의 순서로 출력됨
3.3.1 결괏값 반환받기
void main() async {
final result = await addNumbers(1,1);
print('결과 $result');
final result2 = await addNumbers(2,2);
print('결과 $result2');
}
Future<int> addNumbers(int num1, int num2) async {
print('계산 시작');
await Future.delayed(Duration(seconds: 3), (){
print('$num1 + $num2 = ${num1+num2}');
});
print('계산 끝');
return num1+num2;
}
async / await 키워드를 사용한 함수에서도 결괏값을 반환받을 수 있다.
3.4 Stream
지속적으로 값을 반환받을 때 사용. Stream은 한 번 리슨하면 Stream에 주입되는 모든 값들을 지속적으로 받아온다. (Future은 반환값을 딱 한 번 받아내는 비동기 프로그래밍에 사용)
3.4.1 스트림 기본 사용법
스트림을 사용하려면 dart:async 패키지를 import해야 한다.
그다음 StreamController를 listen() 하면 값을 지속적으로 반환받을 수 있다.
import 'dart:async';
void main() {
final controller = StreamController();
final stream = controller.stream;
//Stream에 listen()함수를 실행하면 값이 주입될 때마다 콜백 함수 실행
final streamListener1 = stream.listen((val){
print(val);
});
//Stream에 값 주입
controller.sink.add(1);
controller.sink.add(2);
controller.sink.add(3);
}
3.4.2 브로드캐스트 스트림
스트림은 단 한 번만(stream)을 사용할 수 있다.
하나의 스트림을 생성하고 여러 번 listen()함수를 실행하려면 브로드캐스트 스트림을 사용한다.
import 'dart:async';
void main() {
final controller = StreamController();
//여러 번 리슨할 수 있는 브로드캐스트스트림 객체 생성
final stream = controller.stream.asBroadcastStream();
//첫번째 listen()
final streamListener1 = stream.listen((val){
print('listening 1');
print(val);
});
//두번째 listen()
final streamListener2 = stream.listen((val){
print('listening 2');
print(val);
});
//add()를 실행할 때마다 listen()하는 모든 콜백함수에 값이 주입됨
controller.sink.add(1);
controller.sink.add(2);
controller.sink.add(3);
}
3.4.3 함수로 스트림 반환하기
StreamController를 직접 사용하지 않고도 직접 스트림을 반환하는 함수를 작성할 수 있다.
Future를 반환하는 함수는 async로 함수를 선언하고 리턴으로 값을 반환
스트림을 반환하는 함수는 async*로 함수를 선언하고 yield 키워드로 값을 반환
import 'dart:async';
Stream<String> calculate(int num) async* {
for(int i=0;i<5;i++){
yield 'i = $i'; //값 반환
await Future.delayed(Duration(seconds: 1));
}
}
void playStream(){
//listen()으로 콜백함수 입력
calculate(1).listen((val){
print(val);
});
}
void main() {
playStream();
}
i = 0부터 1초 간격으로 i =4까지 순차적으로 출력된다.
'[Must Have 코드팩토리의 플러터 프로그래밍]' 카테고리의 다른 글
06 기본 위젯 알아보기 (1) | 2024.04.30 |
---|---|
05 플러터 입문하기 (1) | 2024.04.28 |
04 다트 3.0 신규 문법 (1) | 2024.04.26 |
02 다트 객체지향 프로그래밍 (1) | 2024.04.26 |
01 다트 입문하기 (0) | 2024.04.25 |