동기는 함수를 실행하면 결과값을 바로 받아오지만 비동기는 함수를 실행하면 요청한 결과값을 기다리지 않고 다른 작업을 진행하여 자원을 효율적으로 사용한다.
Future 클래스는 ‘미래’라는 단어의 의미대로 미래에 받아올 값을 뜻한다.
Future<String> name;
Future<int> name;
Future<bool> isOpened;
void main() {
addNumbers(1, 1);
}
void addNumbers(int number1, int number2) {
print("$number1 + $number2 계산 시작!");
Future.delayed(Duration(seconds: 3), (){
print("$number1 + $number2 = ${number1 + number2}");;
});
print("$number1 + $number2 계산 끝!");
}
코드를 작성한 순서대로 실행하고자 할때 사용한다.
Future<void> addNumbers(int number1, int number2) async {
print("$number1 + $number2 = ${number1 + number2}");
await Future.delayed(Duration(seconds: 3), (){
print("$number1 + $number2 = ${number1 + number2}");;
});
print("$number1 + $number2 계산 끝!");
}
void main() async {
await addNumbers(1, 1);
}
Future 클래스를 사용해서 결과값을 받아낼 수 있다.
void main() async {
final result = await addNumbers(1, 1);
final result2 = await addNumbers(2, 2);
}
Future<int> addNumbers(int number1, int number2) async {
print("$number1 + $number2 = ${number1 + number2}");
await Future.delayed(Duration(seconds: 3), (){
print("$number1 + $number2 = ${number1 + number2}");;
});
print("$number1 + $number2 계산 끝!");
return number1 + number2;
}
지속적으로 값을 반환 받을 때는 Stream을 사용한다. 한번 listen하면 Stream에 주입되는 모든 값들을 지속적으로 받아온다.
Future.wait() 함수는 하나의 Future로 구성된 리스트를 매개변수로 입력받는다 . 입력된 비동기 함수들은 모두 동시에 실행되며 응답값을 요청을 보낸 순서대로 저장해둔다.
import "dart:async";
void main() {
final controller = StreamController();
final stream = controller.stream;
final streamListener1 = stream.listen((val) {
print(val);
});
controller.sink.add(1);
controller.sink.add(2);
controller.sink.add(3);
controller.sink.add(4);
}
Stream은 한 번만 listen()을 실행할 수 있다. 하지만 때때로 여러 번 listen() 함수를 실행할때 사용한다. 여러 위젯이 동일한 데이터를 기반으로 갱신되어야 할 때 사용된다.
import "dart:async";
void main() {
final controller = StreamController();
final stream = controller.stream.asBroadcastStream();
final streamListener1 = stream.listen((val) {
print("listen1");
print(val);
});
final streamListener2 = stream.listen((val) {
print("listen2");
print(val);
});
controller.sink.add(1);
controller.sink.add(2);
controller.sink.add(3);
controller.sink.add(4);
}
Stream을 반환하는 함수는 async*로 함수를 선언한다.
import "dart:async";
Stream<String> calculate() async* {
for (int i = 0; i < 5; i++) {
yield "i = $i";
await Future.delayed(Duration(seconds: 1));
}
}
void playStream() {
calculate().listen((val) {
print(val);
});
}
void main() {
playStream();
}
calculate 함수에서 yield가 3.4.2의 controller.sink.add()의 역할을 대신하는 것을 알 수 있다.
이론상으로 Stream가 정확하게 어떻게 쓰이는지 이해가 가지 않지만 플러터 앱 개발을 해보면서 이해한내용을 추가적으로 포스팅할 계획이다.