void main() {
// Future - 미래
// 미래에 받아올 값
Future<String> name = Future.value('코드팩토리');
Future<int> number = Future.value(1);
Future<bool> isTure = Future.value(true);
}
Duration
void main() {
print('함수 시작');
Future.delayed(Duration(seconds:2), (){
print('Delay 끝');
});
}
함수시작
.
. 2초 후
.
Delay 끝
void main() {
addNumbers(1,1);
}
void addNumbers(int number1, int number2){
print('계산시작 : $number1 + $number2');
// 서버 시뮬레이션
Future.delayed(Duration(seconds: 2),(){
print('계산 완료: $number1 + $number2 = ${number1 + number2}');
});
print('함수 완료');
}
계산시작 : 1 + 1
함수 완료
.
. 2초 후
.
계산 완료: 1 + 1 = 2
계산시작 : 1 + 1
출력 후 2초를 기다리고 함수 완료
가 실행되는 것이 아니라 2초가 지나가기 전에 계산 완료: 1 + 1 = 2
가 실행되고 함수 완료
가 실행된다.await
키워드를 사용하기 전에 파라미터와 {}
사이에 async
를 넣어야 한다.Future
와 관련된 함수 (async 함수) 앞에 await
를 작성한다.void main() {
addNumbers(1,1);
}
void addNumbers(int number1, int number2) async {
print('계산시작 : $number1 + $number2');
// 서버 시뮬레이션
await Future.delayed(Duration(seconds: 2),(){
print('계산 완료: $number1 + $number2 = ${number1 + number2}');
});
print('함수 완료 : $number1 + $number2');
}
계산시작 : 1 + 1
.
. 2초 후
.
계산 완료: 1 + 1 = 2
함수 완료 : 1 + 1
계산시작 : 1 + 1
실행된 후 2초 후에계산 완료: 1 + 1 = 2
함수 완료 : 1 + 1
가 실행됐다.- 이 코드만 살펴보면 cpu가 2초 동안 아무것도 안하고 기다리고 있는 것처럼 보인다. 실제로는 그렇지 않다는 것을 증명해 보이면 아래와 같다.
void main() {
addNumbers(1,1);
addNumbers(2,2);
}
void addNumbers(int number1, int number2) async {
print('계산시작 : $number1 + $number2');
// 서버 시뮬레이션
await Future.delayed(Duration(seconds: 2),(){
print('계산 완료: $number1 + $number2 = ${number1 + number2}');
});
print('함수 완료 : $number1 + $number2');
}
계산시작 : 1 + 1
계산시작 : 2 + 2
.
. 2초 후
.
계산 완료: 1 + 1 = 2
함수 완료 : 1 + 1
계산 완료: 2 + 2 = 4
함수 완료 : 2 + 2
- 먼저
addNumbers(1,1)
이 실행되면서계산시작 : 1 + 1
이 출력된다.await
에 걸리면서 2초 동안 실행을 보류하면서 다음 실행할 작업을 찾는다.addNumbers(2,2)
가 실행이 되면서계산시작 : 2 + 2
이 실행된다.- 2초가 지나면 나머지
addNumbers(1,1)
이 실행되고addNumbers(2,2)
이 실행된다 .
addNumbers(1,1)
와 addNumbers(2,2)
를 논리적으로 실행을 할 수 있는 코드를 작성할 수 있다.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: 2),(){
print('계산 완료: $number1 + $number2 = ${number1 + number2}');
});
print('함수 완료 : $number1 + $number2');
}
main()
함수에async
를 작성한다.addNumbers()
에await
를 작성하면 에러가 발생하게 되는데addNumbers()
가Future
를 리턴 해주지 않기 때문이다.addNumbers()
에Future
를 작성하고<void>
를 작성해 주면 된다.
Future
를 실행하게 되면 await
를 통해서 값을 기다리고 한 개의 값을 반환하게 된다.
Future
의 특징은 하나의 함수에서 한 개의 값은 반환한다는 것이다. 일반적으로 모든함수가 동일하다
여러번 값을 받아낼려면 여러번의 함수를 실행해야 한다.
이러한 점을 보완해서 나온 것이 Stream
이다
Stream을 직역해보면 계곡인것처럼 데이터가 계속 흐른다. 이때 yield
라는 키워드를 통해서 계속 값을 반환할 수 있는데 Stream
을 직접 닫을 때까지 사용할 수 있다.
Stream
을 사용하기전에 패키지를 불러와야한다.
import 'dart:async';
import 'dart:async';
void main() {
final controller = StreamController();
// StreamController();는 dart:async에서 불러올 수 있는 클래스이다.
final stream = controller.stream;
// StreamController()를 통해서 stream을 가져올 수 있다.
final streamListener1 = stream.listen((val){
print('Listener 1 : $val');
});
// stream에서 listen() 함수를 사용할 수 있다.
// listen()은 함수를 받게 되는데 들어가는 함수의 파라미터에 값을 받는다.
// 첫번째 파라미터의 값을 듣고 있다가 값이 들어오면 이 함수를 실행하게 되는것이다.
controller.sink.add(1);
// controller에 값을 넣어준다.
}
Listener 1 : 1
import 'dart:async';
void main() {
final controller = StreamController();
final stream = controller.stream;
// controller.stream에서는 기본적으로 한번만 리스닝을 할 수 있는 리소스가 생긴다.
// asBroadcastStream();를 뒤에 붙이면 여러번 리스닝을 사용할 수 있다.
final streamListener1 = stream.listen((val){
print('Listener 1 : $val');
});
final streamListener2 = stream.listen((val){
print('Listener 2 : $val');
})
// 리스너2를 선언했다.
controller.sink.add(1);
controller.sink.add(2);
controller.sink.add(3);
controller.sink.add(4);
controller.sink.add(5);
}
Listener 1 : 1
Listener 2 : 1
Listener 1 : 2
Listener 2 : 2
Listener 1 : 3
Listener 2 : 3
Listener 1 : 4
Listener 2 : 4
Listener 1 : 5
Listener 2 : 5
import 'dart:async';
void main() {
final controller = StreamController();
final stream = controller.stream.asBroadcastStream();
final streamListener1 = stream.where((val) => val % 2 == 0).listen((val) {
print('Listener 1 : $val');
});
// 함수형 프로그래밍에서 사용했던 함수를 사용할 수 있다.
// where를 사용해서 짝수와 홀수를 구분해서 출력한다.
final streamListener2 = stream.where((val) => val % 2 == 1).listen((val) {
print('Listener 2 : $val');
});
controller.sink.add(1);
controller.sink.add(2);
controller.sink.add(3);
controller.sink.add(4);
controller.sink.add(5);
}
Listener 2 : 1
Listener 1 : 2
Listener 2 : 3
Listener 1 : 4
Listener 2 : 5