Dart #4 비동기프로그래밍

최민경·2023년 3월 21일

Flutter

목록 보기
4/5
  • Thred: 작업 최소 단위

  • Asynchronous 프로그래밍을 사용하면 CPU를 효율적으로 사용할 수 있음

1. Synchronous programming

2. Future, delayed(), Duration()


3. await - async

  • 서버에 요청하고 결과값을 받아올 때는 무조건 아래 '서버 시뮬레이션'처럼 시간이 걸림

  • 따라서 함수를 순차적으로 짜면 안되고, 지연되는 시간을 고려해서 로직을 짜면 코드가 복잡해짐

  • 이를 해결하기 위한 것이 await임

  • await 키워드인 'async'는 함수파라미터()와 함수바디{} 사이에 적으면 됨

  • await는 관련 async 함수 앞에 씀

  • await 다음에 실행될 함수들은 잠시 대기하지만,

  • 다른 코드를 실행할 수 있는 여지가 있으면 cpu처리가 진행됨.

  • 모든 함수에 Future 사용 가능

  • return 값도 받아올 수 있음
  • 함수 선언할 때 Future 뒤에 반환타입만 지정해주면 됨

4. Stream

  • Future은 하나의 함수를 통해서 하나의 값을 받아옴

  • Stream을 닫을 때까지 데이터를 무한하게 받을 수 있음
  • 그만큼 복잡함

  • 코드 예시
// Stream은 패키지를 불러와야 사용할 수 있음
import 'dart:async';

void main() async {
  // dart:async패키지에서 StreamController 클래스를 불러옴
  final controller = StreamController();
  final stream = controller.stream;

  // stream에 있는 listen()함수를 불러옴
  // listen()에는 함수를 파라미터로 받으며, 해당 함수파라미터에도 한 개의 파라미터를 입력함
  final streamLister1 = stream.listen((val) {
    print('Listener 1: $val');
  });
  
  // .add()함수를 통해 controller에 값을 넣어주면, Listener에 값이 들어감
  // stream은 여러 개의 값을 돌려줄 수 있음
  controller.sink.add(1);
  controller.sink.add(2);
  controller.sink.add(3);
  controller.sink.add(4);
  controller.sink.add(5);
}
  • final stream = controller.stream; -> 기본적으로 한 번만 Listener를 할 수 있음
  • asBroadcastStream();을 통해 여러 개의 Listener 생성하기

  • where()로 조건 추가하기
  • 이런식으로 다른 함수형 프로그래밍도 추가할 수 있음
  • 이를 통해 데이터가 들어오는 순간에 변형하기

import 'dart:async';

void main() {
  calculate(2).listen((val){
    print('calculate(2): $val');
  });
  
  calculate(4).listen((val){
    print('calculate(4): $val');
  });

}




Stream<int> calculate(int number) async*{
  for(int i = 0; i < 5; i++){
    yield i * number;
    
    await Future.delayed(Duration(seconds:1));
  }
}

import 'dart:async';

void main() {
//   // async로 동시에 두 함수가 동시에 실행됨
//   calculate(2).listen((val){
//     print('calculate(2): $val');
//   });
  
//   calculate(4).listen((val){
//     print('calculate(4): $val');
//   });
  
  playAllStream().listen((val){
    print(val);
  });
}

// yield*을 쓰면 앞 함수가 다 실행되어야 다음 함수가 실행됨
Stream<int> playAllStream() async*{
  yield* calculate(1);
  yield* calculate(1000);
}

Stream<int> calculate(int number) async*{
  for(int i = 0; i < 5; i++){
    yield i * number;
    
    // 1초 뒤 다음 loop 실행
    await Future.delayed(Duration(seconds:1));
  }
}

0개의 댓글