다트는 동기/비동기 프로그래밍을 지원한다.
동기 : 요청을 하고 나서 응답이 올 때까지 기다렸다가 응답.
비동기 : 요청을 하고 나서 응답을 받지 않아도 다음 코드를 진행. 추후에 응답이 오면 처리.
Future
- Future 클래스 : 미래에 제너릭으로 값을 받아옴.
// 일정 시간 후 콜백 함수 실행.
// Future.delayed
void main() {
print("실행 시작");
Future.delayed(Duration(seconds: 3), (){
print('3초 후 실행합니다.');
});
print("실행 완료?");
}
// 실행 결과(비동기로 동작)
실행 시작
실행 완료?
3초 후 실행합니다.
async, await
- 코드를 순서대로 실행시키기 위해 사용
void main() {
addNumbers(1, 1);
}
// async 키워드는 함수 매개변수 정의와 바디 사이에 입력.
void addNumbers(int number1, int number2) async {
print('$number1 + $number2 계산 시작!');
// await는 대기하고 싶은 비동기 함수 앞에 입력.
await Future.delayed(Duration(seconds: 3), (){
print('$number1 + $number2 = ${number1 + number2}');
});
print('$number1 + $number2 코드 실행 끝');
}
// 실행 결과
1 + 1 계산 시작!
1 + 1 = 2
1 + 1 코드 실행 끝
비동기적으로 동작하는 지 확인
void main() {
addNumbers(1, 1);
addNumbers(2, 2);
}
Future<void> addNumbers(int number1, int number2) async {
print('$number1 + $number2 계산 시작!');
await Future.delayed(Duration(seconds: 3), (){
print('$number1 + $number2 = ${number1 + number2}');
});
print('$number1 + $number2 코드 실행 끝');
}
// 실행 결과
1 + 1 계산 시작!
2 + 2 계산 시작!
1 + 1 = 2
1 + 1 코드 실행 끝
2 + 2 = 4
2 + 2 코드 실행 끝
두 함수를 순차적으로 실행하고 싶다면...
// main 함수에 async, await 사용.
void main() async {
await addNumbers(1, 1);
await addNumbers(2, 2);
}
Future<void> addNumbers(int number1, int number2) async {
print('$number1 + $number2 계산 시작!');
await Future.delayed(Duration(seconds: 3), (){
print('$number1 + $number2 = ${number1 + number2}');
});
print('$number1 + $number2 코드 실행 끝');
}
// 실행 결과
1 + 1 계산 시작!
1 + 1 = 2
1 + 1 코드 실행 끝
2 + 2 계산 시작!
2 + 2 = 4
2 + 2 코드 실행 끝
결과 값을 비동기로 리턴 받고 싶다면...
void main() async {
final result = await addNumbers(1, 1);
print('결과값 $result'); // 일반 함수와 동일하게 반환값을 받을 수 있음
final result2 = await addNumbers(2, 2);
print('결과값 $result2');
}
Future<int> addNumbers(int number1, int number2) async {
print('$number1 + $number2 계산 시작!');
await Future.delayed(Duration(seconds: 3), (){
print('$number1 + $number2 = ${number1 + number2}');
});
print('$number1 + $number2 코드 실행 끝');
return number1 + number2;
}
//
1 + 1 계산 시작!
1 + 1 = 2
1 + 1 코드 실행 끝
결과값 2
2 + 2 계산 시작!
2 + 2 = 4
2 + 2 코드 실행 끝
결과값 4
Stream
- Future 는 결과값을 한번 리턴.
- 지속적으로 리턴받고 싶을 때는 Stream 을 사용.
- Stream 은 한번 Listen 하면 지속적으로 값을 받아온다.
import 'dart:async';
void main() {
final controller = StreamController(); // StreamController 선언
final stream = controller.stream; // Stream 가져오기
// Stream에 listen() 함수를 실행하면 값이 주입될 때마다 콜백 함수를 실행
final streamListener1 = stream.listen((val) {
print(val);
});
// Stream에 값을 주입할 때는 sink.add() 함수를 실행
controller.sink.add(1);
controller.sink.add(2);
controller.sink.add(3);
controller.sink.add(4);
}
// 실행 결과
1
2
3
4
Broadcasting
- Stream 을 여러번 Listen 하기
import 'dart:async';
void main() {
final controller = StreamController();
// 여러 번 listen할 수 있는 Broadcast Stream 객체 생성
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);
}
// 실행 결과.
listening 1
1
listening 2
1
listening 1
2
listening 2
2
listening 1
3
listening 2
3
함수로 Stream 반환하기
- 이건 잘 모르겠음. --;;
import 'dart:async';
// Stream을 반환하는 함수는 async*로 선언합니다.
Stream<String> calculate() async* {
for (int i = 0; i < 5; i++) {
// StreamController의 add()처럼 yield 키워드를 이용해서 값 반환
yield 'i = $i';
await Future.delayed(Duration(seconds: 1));
}
}
void playStream() {
// StreamController와 마찬가지로 listen() 함수로 콜백 함수 입력
calculate().listen((val) {
print(val);
});
}
void main() {
playStream();
}
// 실행 결과(1초에 한줄씩 출력)
i = 0
i = 1
i = 2
i = 3
i = 4
이번에는 비동기 프로그래밍에 대해서 알아봤다.
점점 어려워지는구만..ㅋㅋ