Dart | Dart #4 Async Programming

앙두·2023년 7월 8일
0

for My Programming

목록 보기
13/20

Dart : 비동기 프로그래밍

인프런 무료 강의
https://www.inflearn.com/course/lecture?courseSlug=dart-%EC%96%B8%EC%96%B4-%EC%9E%85%EB%AC%B8&unitId=107600
DartPad
https://dartpad.dev/


Async Programming

그가 왔다..

Future

  • async 기능을 함
  • 미래에 받아올 값
Future.delayed(Duration(seconds: 3), () => print('Delay end.'));
// 3초 후 'Delay end.'가 출력된다.
  • Future.delayed 를 사용하여 함수를 지연실행시킬 수 있다.
  • 2개의 parameter가 필요하다

    Future.delayed(Duration, Function after duration)

void main() async {
  Future<String> name = Future.value('coding ');
  Future<int> num = Future.value(1);
  Future<bool> isTrue = Future.value(true);
  
  // 해당 함수에 await을 걸어주려면, 위에 async를 추가!
  // addNum 함수도 비동기가 되도록 Future를 붙여줘야 한다.
  await addNum(5, 8);
  substractNum(3, 1);
}

Future<void> addNum(num1, num2) async {
  print('Async 계산 시작');
  
  await Future.delayed(Duration(seconds: 5), () => print('합한 값은 ${num1 + num2}'));
  // 5초 후에 '합한 값은 13' 출력됨
  
  print('Async 계산 종료');
}

void substractNum(num1, num2) {
  print('$num1 - $num2');
}
  • await 를 쓰려면 async 를 먼저 표기해줘야 함
  • await 으로 기다려준다고 해서, 다른 작업을 하지 않는 게 아니다.
  • CPU가 놀고 있지 않는다. 다른 작업도 같이 함. 그게 비동기니깐.
  • addNum()함수가 종료가 돼야 substractNum()이 실행된다.
void main() async {
  Future<String> name = Future.value('coding ');
  Future<int> num = Future.value(1);
  Future<bool> isTrue = Future.value(true);

  final result = await addNum(5, 8); (1)

  print('* 결과는 : $result'); // (5)
}

Future<int> addNum(num1, num2) async {
  print('Async 계산 시작'); // (2)

  await Future.delayed(
      Duration(seconds: 5), () => print('합한 값은 ${num1 + num2}')); // (3)

  print('Async 계산 종료'); // (4)

  return num1 + num2;

  // Async 계산 시작
  // 합한 값은 13
  // Async 계산 종료
  // * 결과는 : 13
}

Stream

  • streamimportpackage를 불러와 사용한다.
  • import 'dart:async'
import 'dart:async';

void main() {
  final controller = StreamController();
  final stream = controller.stream;

  // Listener 가 듣는 역할을 함
  final streamListener1 = stream.listen((val) {
    print('Listener 1 : $val');
  });

  // Listener 에게 값을 전달해주는 역할
  controller.sink.add('hi!');
  controller.sink.add('salut!');
  controller.sink.add('Do u hear me?');
  controller.sink.add('Est-ce que tu m\'entends?');
}
// Listener 1 : hi!
// Listener 1 : salut!
// Listener 1 : Do u hear me?
// Listener 1 : Est-ce que tu m'entends?
  • Listener 에게 원하는 값을 넣어준다.
  • Listener 가 그 값을 듣고 실행시켜 출력한다.
  • 나도 이 Listener는 굉장히 생소하다 🤔

import 'dart:async';

void main() {
  final controller = StreamController();
  final stream = controller.stream.asBroadcastStream();

  // Listener 가 듣는 역할을 함
  final streamListener1 = stream.listen((val) {
    print('Listener 1 : $val');
  });
  
  final streamListener2 = stream.listen((val) {
    print('Listener 2 : $val');
  });

  // Listener 에게 값을 전달해주는 역할
  controller.sink.add('hi!');
  controller.sink.add('salut!');
  controller.sink.add('Do u hear me?');
  controller.sink.add('Est-ce que tu m\'entends?');
}
// Listener 1 : hi!
// Listener 2 : hi!
// Listener 1 : salut!
// Listener 2 : salut!
// Listener 1 : Do u hear me?
// Listener 2 : Do u hear me?
// Listener 1 : Est-ce que tu m'entends?
// Listener 2 : Est-ce que tu m'entends?
  • Listener가 원래는 하나밖에 listen을 못한다.
  • 여러개의 Listener를 동작시키고 싶으면 controller.stream뒤에 .asBroadcastStream() 를 붙여준다.

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 even : $val');
  });
  
  final streamListener2 = stream.where((val) => val % 2 == 1).listen((val) {
    print('Listener odd : $val');
  });

  controller.sink.add(40); // Listener even : 40
  controller.sink.add(9); // Listener odd : 9
  controller.sink.add(82); // Listener even : 82
  controller.sink.add(1); // Listener odd : 1
}
  • Listener 자체에서 functional programming 도 직접 가능하다.
  • 뿌려주는 값을 코드에 맞게 계산해서, Listener 가 출력해준다.

  • Streamasync / await 을 사용하고 싶을 때
import 'dart:async';

void main() {
  // calculate 함수를 호출하면서 파라미터로 값을 뿌려주면
  // listener 가 듣고 실행함
  calculate(2).listen((val){
    print('calculate(2) : $val');
  });
}

// async*
Stream<int> calculate(int number) async* {
  for(int i = 0; i < 5; i++){
    yield i * number;
  }
}
// calculate(2) : 0
// calculate(2) : 2
// calculate(2) : 4
// calculate(2) : 6
// calculate(2) : 8
  • Future는 그냥 async를 썼다면,
  • Streamasync 뒤에 별표 표기를 한다.
  • return 대신에 yield 를 쓴다.

  • Streamawait 도 써주고 싶을 때
import 'dart:async';

void main() {
  playAllStream().listen((val) => print('play async await => $val'));
}

// 파라미터없이, calculate()를 실행하는 함수만 넣은 Stream 이다.
Stream<int> playAllStream() async* {
  // yield*
  yield* calculate(3);
  // calculate(3) 끝나야 밑에가 실행
  yield* calculate(7);
}

Stream<int> calculate(int number) async* {
  for(int i = 0; i < 5; i++){
    yield i * number;
    
    // 1초에 한번씩 실행된다.
    await Future.delayed(Duration(seconds: 1));
  }
}
// play async await => 0
// 1초 뒤 : play async await => 3
// 1초 뒤 : play async await => 6
.
.
.
  • Streamawait을 걸어주고 싶다면 async와 같이 yield 뒤에도 별표를 표기한다.
  • 아무튼, Future 와 다른 점은 async await을 별표표기로 한다는 것
profile
쓸모있는 기술자

0개의 댓글