[플러터] 3. 다트 비동기 프로그래밍

Jun·2024년 2월 12일
0

이번장은 다트 언어를 사용해 비동기 프로그래밍을 하는 방법에 대해 소개합니다.

Future

Future 클래스를 이용하여 미래에 받아올 값을 정의합니다.

Future<String> name;

특정 기간동안 아무것도 하지 않고 기다리는 Future.delayed()를 사용하여 예시를 보겠습니다.

void main() {
  addNumbers(1, 1);
}

void addNumber(int num1, int num2) {
  print('$num1 + $num2 계산 시작!');
  Future.delayed(Duration(seconds: 3), () => {
    print('$num1 + $num2 = ${num1 + num2}');
  })
  print('코드 실행 끝');
}
1 + 1 계산 시작!
코드 실행 끝
1 + 1 = 2

async와 await

void main() {
  addNumbers(1, 1);
}

Future<void> addNumber(int num1, int num2) async {
  print('$num1 + $num2 계산 시작!');
  await Future.delayed(Duration(seconds: 3), () => {
    print('$num1 + $num2 = ${num1 + num2}');
  })
  print('코드 실행 끝');
  
  return num1 + num2;
}

/* 결과
1 + 1 계산 시작!
1 + 1 = 2
코드 실행 끝
*/
void main() {
  addNumbers(1, 1);
  addNumbers(2, 2);
}

/* 결과
1 + 1 계산 시작!
2 + 2 계산 시작!
1 + 1 = 2
코드 실행 끝
2 + 2 = 4
코드 실행 끝
*/
void main() async {
  await addNumber(1, 1);
  await addNumber(2, 2);
}

/* 결과
1 + 1 계산 시작!
1 + 1 = 2
코드 실행 끝
2 + 2 계산 시작!
2 + 2 = 4
코드 실행 끝
*/

결괏값 반환받기

void main() async {
  final result = await addNumber(1, 1); // 2
}

Future.wait()

Future로 구성된 리스트를 매개변수로 입력받습니다.
해당 비동기 함수들은 모두 동시에 실행되며 응답값을 요청을 보낸 순서대로 저장합니다.
(js의 promise.all과 유사)

Stream

Future는 반환값을 딱 한 번 받아내는 비동기 프로그래밍에 사용됩니다.
지속적으로 값을 반환 받을 때는 Stream을 사용합니다.

기본 사용법

사용하기 위해선 플러터에서 기본으로 제공하는 dart:async 패키지를 불러와야합니다.

import 'dart:async';

void main() {
  final controller = StreamController(); // StreamController 선언
  final stream = controller.stream; // Stream 가져오기
  // stream의 listen() 함수를 실행하면 값이 주입될 때마다 콜백 함수를 실행할 수 있습니다.
  final streamListener = stream.listen((val) => {
    print(val);
  });
  
  controller.sink.add(1); // 1 출력
  controller.sink.add(2); // 2 출력
}

브로드캐스트 스트림

Stream은 단 한 번만 listen()을 실행할 수 있습니다.
반면에 브로드캐스트 스트림을 사용하면 Stream을 여러번 listen() 하도록 변환할 수 있습니다.

import 'dart:async';

void main() {
  final controller = StreamController();
  final stream = controller.stream.asBroadcastStream();
  
  final streamListener1 = stream.listen((val) => {
    print('listener1 $val');
  });
  
  final streamListener2 = stream.listen((val) => {
    print('listener2 $val');
  })
  
  controller.sink.add(1);
  controller.sink.add(2);
  
  /*결과
  listener1 1
  listener2 1
  listener1 2
  listener2 2
  */
}

함수로 Stream 반환하기

StreamController를 사용하지 않고도 Stream을 반환하는 함수를 작성할 수 있습니다.

import 'dart:async';

// Stream을 반환하는 함수는 async*로 선언합니다.
Stream<String> countDown(int number) async* {
  for (int i=number; i>0; i--) {
    yield '$i';
    await Future.delayed(Duration(seconds:1));
  }
}

void playStream() {
  countDown(5).listen((val) => {
    print(val);
  });
}

void main() {
  playStream();
}

/*결과
5
4
3
2
1
*/

《Must Have 코드팩토리의 플러터 프로그래밍 2판》의 스터디 내용 입니다.

profile
HiHi

0개의 댓글