3단계 다트 비동기 프로그래밍

송기영·2023년 11월 28일
0

플러터

목록 보기
5/25

3.1. 동기 vs 비동기 프로그래밍

동기는 함수를 실행하면 결과값을 바로 받아오지만 비동기는 함수를 실행하면 요청한 결과값을 기다리지 않고 다른 작업을 진행하여 자원을 효율적으로 사용한다.

3.2. Future

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 계산 끝!");
}

3.3. async와 await

코드를 작성한 순서대로 실행하고자 할때 사용한다.

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);
}

3.3.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;
}

3.4. Stream

지속적으로 값을 반환 받을 때는 Stream을 사용한다. 한번 listen하면 Stream에 주입되는 모든 값들을 지속적으로 받아온다.

Future.wait() 함수는 하나의 Future로 구성된 리스트를 매개변수로 입력받는다 . 입력된 비동기 함수들은 모두 동시에 실행되며 응답값을 요청을 보낸 순서대로 저장해둔다.

3.4.1. Stream 기본 사용법

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);
}

3.4.2. 브로드캐스트 스트림

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);
}

3.4.3. 함수로 Stream 반환하기

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가 정확하게 어떻게 쓰이는지 이해가 가지 않지만 플러터 앱 개발을 해보면서 이해한내용을 추가적으로 포스팅할 계획이다.

profile
업무하면서 쌓인 노하우를 정리하는 블로그🚀 풀스택 개발자를 지향하고 있습니다👻

0개의 댓글