동기 / 비동기
- 동기 : 요청을 하면 응답을 받을 때 까지 기다림
- 비동기 : 요청을 한 후 대기하지 않고 다른 거 하다가 요청 오면 그거 받음
Future
- 클래스
- 미래 어떤 값을 받을 지 지정가능
void main(){
Future<String> name; // 미래에 받을 String값
Future<int> number; // 미래에 받을 int값
Future<bool> isOpened; // 미래에 받을 boolean값
}
void main() {
addNumbers(1, 1);
}
void addNumbers(int number1, int number2){
print('$number1 + $number2 계산 시작!');
// ➊ Future.delayed()를 사용하면 일정 시간 후에 콜백 함수를 실행할 수 있음
Future.delayed(Duration(seconds: 3), (){
print('$number1 + $number2 = ${number1 + number2}');
});
print('$number1 + $number2 코드 실행 끝');
}
- Future.delayed()라는 함수로 일정 시간 후에 이거 실행하겠다고 선언한거라 그 밑에거 처리하고 그 다음 요청받아서 결과가 아래처럼 됨
1 + 1 계산 시작!
1 + 1 코드 실행 끝
1 + 1 = 2
async / await
- 비동기로 cpu를 효율적으로 쓰도록 Future를 써서 할 수가 있지만 비동기를 동기처럼 동작 시키고 싶을 때가 있음
- 순서대로 실행 시키기 위해서 async . await 를 사용
- async를 함수에 쓴다 = 해당 함수는 비동기 함수다
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 코드 실행 끝');
}
- 함수에 asnyc지정 하고 함수 실행시 await를 사용해서 코드를 작성한 순서대로 실행
void main() {
addNumbers(1, 1);
addNumbers(2, 2);
}
// async 키워드는 함수 매개변수 정의와 바디 사이에 입력합니다.
Future<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 코드 실행 끝');
}
- addNumber()함수가 Future함수로 비동기 함수임 이거 실행하고 결과를 기다리지 않음 짜피 await도 없으니까 결과 기다리지 않고 addNumbers()함수를 2번 실행한 거임
- delayed()가 끝나고 그 다음 요청 결과를 기다려서 화면에 출력됨
1+ 1 계산 시작!
2 + 2 계산 시작!
1 + 1 = 2
1 + 1 코드 실행 끝
2 + 2 = 4
2 + 2 코드 실행 끝
동기적로 동작하길 원하면 함수 호출 시 await를 붙이자
await는 비동기 함수에서만 쓸 수 있어서 async를 main에 써줌
void main() async {
await addNumbers(1, 1);
await addNumbers(2, 2);
}
// async 키워드는 함수 매개변수 정의와 바디 사이에 입력합니다.
Future<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 코드 실행 끝
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;
}
정리 : chatgpt
- await:
- await는 비동기 함수 내에서만 사용될 수 있습니다.
- await 키워드는 비동기 함수 호출 앞에 붙여 사용하며, 해당 함수의 실행이 완료될 때까지 현재 함수의 실행을 일시 중단합니다.
- await 키워드를 사용하여 비동기 함수의 결과를 기다린 다음, 해당 결과를 반환하거나 변수에 할당할 수 있습니다.
- await 키워드는 Future 객체나 비동기 함수의 반환 타입이 있는 다른 비동기 작업을 기다릴 때 사용됩니다.
- async:
- async 키워드는 함수의 선언부에 추가되며, 해당 함수가 비동기 함수임을 나타냅니다.
- 비동기 함수는 Future 객체를 반환하는 함수입니다.
- async 함수 내에서는 await 키워드를 사용하여 비동기 작업의 실행을 기다릴 수 있습니다.
- async 함수는 비동기 작업을 순차적으로 실행하면서 다른 작업들을 동시에 처리할 수 있습니다.
Stream
- Future는 단 한 번만 값을 받아내는 비동기
- Stream은 한번 listen때리면 지속적으로 모든 값들을 받아냄
1. 기본 사용법
- dart:async 패키지 필요
- StreamController가 필요 : 이 컨트롤러로 스트림을 가져올 수 있음
- 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);
}
2. 브로드캐스팅 스트림
- 스트림은 원래 한 번만 리슨 실행가능
- 하나의 스트림을 만들고 여러번 리슨하고 싶을 때 브로드캐스트 스트림을 사용하면 됨
import 'dart:async';
void main() {
final controller = StreamController();
// 여러 번 리슨할 수 있는 Broadcaste 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);
}
- 컨트롤러에 데이터 변화가 있을 때 복수의 Listen함수에서 데이터 변화를 감지하고 내부 로직을 실행
listening 1
1
listening 2
1
listening 1
2
listening 2
2
listening 1
3
listening 2
3
3. 함수로 스트림 반환하기
-StreamController선언하지 않고도 스트림 반환 가능
- Future반환하는 함수는 async쓰고 return으로 값 반환
- Stream반환하는 함수는 asnyc* 쓰고 yield로 값 반환
import 'dart:async';
// Stream을 반환하는 함수는 async*로 선언합니다.
Stream<String> calculate(int number) 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(1).listen((val) {
print(val);
});
}
void main() {
playStream();
}
- 1초마다 값을 리턴하는 함수에 리슨 달아서 값 변화 관측하고 출력함
i = 0
i = 1
i = 2
i = 3
i = 4
참고
“이 글은 골든래빗 《Must Have 코드팩토리의 플러터 프로그래밍 2판》의 스터디 내용 입니다.”
'프로그래밍 > 플러터' 카테고리의 다른 글
Unable to boot the Simulator (0) | 2024.02.19 |
---|---|
Getters and Setters (0) | 2024.02.18 |
다트 객체지향 프로그래밍 (1) | 2024.02.10 |
다트 기본 문법 [변수 , 컬랙션, 람다] (1) | 2024.02.10 |
플러터 안드로이드 스튜디오 세팅 (0) | 2024.01.27 |
하고 싶은 걸 하고 되고 싶은 사람이 되자!
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!