Async

void main(){
  // Future - 미래
  // 미래에 받아올 값
  Future<String> name = Future.value('코드팩토리');
  Future<int> number = Future.value(1);
  Future<bool> number = Future.value(truew);

  // 2개의 파라미터
  // delayed - 지연되다.
  // 1번 파라미터 - 지연할 기간 (얼마나 지연할 건지) duration
  // 2번 파라미퉈 - 지연시간이 지난 후 실행할 함수

  addNumbers(1,1);
  addNumbers(2,2);
}

void addNumbers(int number1, int number2){
  print('계산 시작: $number1 + $number2');

  // 서버 시뮬레이션 
  Future.delayed(Duration(seconds: 2), (){
    print('계산 완료: $number1 + $number2 = ${number1+number2}');
  });

  print('함수 완료');
}

결과

계산 시작 1+1
함수 완료
계산 시작 2+2
함수 완료
계산 완료 1+1 = 2
계산 완료 2+2 = 4

이런식으로 실행이 됨.

await

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

void addNumbers(int number1, int number2) async{
  print('계산 시작: $number1 + $number2');

  // 서버 시뮬레이션 
  await Future.delayed(Duration(seconds: 2), (){
    print('계산 완료: $number1 + $number2 = ${number1+number2}');
  });

  print('함수 완료 : $number1 + $number2');
}

무언가 기다렸다가 활용해야한다고 하면 await를 써야한다.

Future 를 return 해주는 함수 앞에는 await를 넣어줄 수 있다.

저렇게 하면…

계산 시작 1+1
계산 시작 2+2
계산 완료 1+1 = 2
계산 완료 2+2 = 4
함수 완료
함수 완료

위와 같이 됨. await 를 하고 그 다음에 print를 진행하는데 그 기다리는 동안 다른 작업도 할 수 있으면 또 작업을 함.

void main() async {
  await addNumbers(1,1);
  await addNumbers(2,2);
}
...

Future<void> addNumbers(..) async {
  ..
}

이런식으로 해주면 addNumbers 자체도 비동기로 실행시킬 수 있다.

void main() async{
  final number1 = await addNumbers(1,1);
  final number2 = await addNumbers(2,2);
}

Future<int> addNumbers(int number1, int number2) async{
  print('계산 시작: $number1 + $number2');

  // 서버 시뮬레이션 
  await Future.delayed(Duration(seconds: 2), (){
    print('계산 완료: $number1 + $number2 = ${number1+number2}');
  });

  print('함수 완료 : $number1 + $number2');

  return number1 + number2;
}

Stream

이건 진짜 어렵고, flutter에서 많이 사용하는 개념이얌.

Future 에서는

실행 .. await .. 완료 반환값을 받게 됨

Stream 실행 ..yield..yield..yield..yield..yield.. 완료

개울이야.. 무한하게 받을 수 있어 계속 받을 수 있어

눈에 띄는 장점은 한순간에만 받는 것이 아니라, 지속적으로 받게 해준다는 거야..

Stream을 사용하려면 패키지를 가져와야 해

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 1  : $val');
  })

  final streamListener2 = stream.where((val)=>val%2==1).listen((val){
    // 값을 듣고 있을 때 값이 들어오면 이 값이 실행이 됨.
    print('Listener 2  : $val');
  })

  controller.sink.add(1);
  controller.sink.add(2);
  controller.sink.add(3);
  controller.sink.add(4);
  controller.sink.add(5);

}

이런식으로 리스닝을 할 수 있음.

정리하면 yield로 데이터를 발생시키면! 그걸 listen하는 쪽에서 받아서 사용할 수 있게 한다는 것 여러가지를 만들 수도 있고 그리고 그 data를 보내고 받는 걸 비동기로 할 수 있다는 것.

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

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

  playAllStream().listen((val){
    print(val);
  });
}

Stream<int> playAllStream() async*{
  yield* calculate(1); // yield* 을 쓰면 그 값이 모두 다 가져올 때 까지 기다린다.
  yield* calculate(1000);
}

// Stream에서 async 사용하는 방법
Stream<int> calculate(int number) async* {
  for(int i=0; i<5; i++){
    yield i * number;

    await Future.delayed(Duration(seconds: 1)); // Stream 속에서 await를 사용할 수도 있다.
  }
}// 이렇게하면 리스너에다 값을 뿌려줄 수 있음