본문 바로가기
TIL

[TIL] 비동기 프로그래밍

by chengzior 2024. 11. 4.

 

비동기 프로그래밍
작업이 완료될 때까지 기다리지 않고, 미래의 특정 시점에 값을 반환
수행할 수 있는 다른 작업을 찾아서 수행


Future
: 비동기 프로그래밍에서 사용되는 대표적인 클래스

  • 작업이 성공적으로 완료되었을 때 해당 결과값을 반환하고, 실행을 종료

void main() {
  int seconds =2;
  print("실행시작");
  Future.delayed(Duration(seconds: seconds), (){
  	print('$seconds초 다 기다림');
  });
  print('실행 끝');
}
void introduce(String name){
  print('$name의 자기소개 시작!');
  
  Future.delayed(Duration(seconds:2), () {
    print('안녕 나는 $name이야');
  });
  
  print('$name의 자기소개 끝');
}

void main() {
  introduce('홍길동');
}

//결과:
//홍길동의 자기소개 시작!
//홍길동의 자기소개 끝
//안녕 나는 홍길동이야

비동기적으로 실행되었기 때문에 '안녕 나는~'보다 '자기소개 끝'이 먼저 실행됨.

void introduce(String name) {
	print('$name의 자기소개 시작 !');
  
  Future.delayed(Duration(seconds: 2), () {
    print('안녕 ? 나는 $name ~');
  });
	
	print('$name의 자기소개 끝 !');
}

void main() {
  introduce('강미래');
  introduce('강현재');
}

/*
강미래의 자기소개 시작 !
강미래의 자기소개 끝 !
강현재의 자기소개 시작 !
강현재의 자기소개 끝 !
안녕 ? 나는 강미래 ~
안녕 ? 나는 강현재 ~
*/

 

async-awit
코드 순서대로 실행시키고 싶을 때
비동기적인 코드 앞에 
async를 붙이고, await 를 붙인 코드를 포함하는 함수에 async 를 붙이면 된다


void introduce(String name) async {
  print('$name의 자기소개 시작!');
  
  await Future.delayed(Duration(seconds:2), () {
    print('안녕 나는 $name이야');
  });
  
  print('$name의 자기소개 끝');
}

void main() {
  introduce('홍길동');
}
/*
결과:
홍길동의 자기소개 시작!
안녕 나는 홍길동이야
홍길동의 자기소개 끝*/

 

동기적으로 실행되느냐 -> 아님 비동기적으로 실행됨.

void introduce(String name) async {
	print('$name의 자기소개 시작 !');
  
  await Future.delayed(Duration(seconds: 2), () {
    print('안녕 ? 나는 $name ~');
  });
	
	print('$name의 자기소개 끝 !');
}

void main() {
  introduce('강미래');
  introduce('강현재');
}

/*
강미래의 자기소개 시작 !
강현재의 자기소개 시작 !
안녕 ? 나는 강미래 ~
강미래의 자기소개 끝 !
안녕 ? 나는 강현재 ~
강현재의 자기소개 끝 !
*/

 

순서대로 실행하고 싶을 때: main에서 await 사용해준다.

Future<void> introduce(String name) async {
	print('$name의 자기소개 시작 !');
  
  await Future.delayed(Duration(seconds: 2), () {
    print('안녕 ? 나는 $name ~');
  });
	
	print('$name의 자기소개 끝 !');
}

void main() async {
  await introduce('강미래');
  await introduce('강현재');
}

/*
강미래의 자기소개 시작 !
안녕 ? 나는 강미래 ~
강미래의 자기소개 끝 !
강현재의 자기소개 시작 !
안녕 ? 나는 강현재 ~
강현재의 자기소개 끝 !
*/

주의))
await
 는 Future 류의 코드 앞에만 사용할 수 있다고 했기 때문에 introduce() 의 반환 타입을 Future<void> 로 바꿔 주어야 함
await 를 포함하는 함수에는 반드시 async 를 붙여야 한다고 했기 때문에 main() 에 async 를 붙여 주어야 함 
introduce() 는 반환값이 없기 때문에 (return 구문이 없기 때문에) Future<void> 타입으로 해주는 것
async 함수 안에 await 가 여러 번 있어도 된다

Future의 단점
:
하나의 작업당 결과값을 1번만 받을 수 있음

 


Stream
: 비동기 프로그래밍에서 사용되는 대표적인 클래스

  • 시간에 따라 연속적인 데이터 흐름을 제공
  • 한 번에 하나의 값이 아닌 여러 값을 비동기적으로 받을 수 있음
  • 직접 실행을 종료해 주어야 실행이 종료되고, 실행을 종료해 주지 않으면 계속 실행됨

 

Stream<String> emitNames() async* {
  yield '강미래';
  yield '강현재';
  yield '강과거';
}

yield: 값을 방출

listen: yield를 통해 방출되는 값을 받기 위해 사용하는 메서드

Stream<String> emitNames() async* {
  yield '강미래';
  yield '강현재';
  yield '강과거';
}

void main() {
  int number = 1;
  
  emitNames().listen((name) {
    print('$number번째는 $name ~');
    number += 1;
  });
}

/*
1번째는 강미래 ~
2번째는 강현재 ~
3번째는 강과거 ~
*/
Stream<int> emitNumbers(int first) async* {
  for(var i = first; i>=0;i--){
    yield i;
  }
}

void main(){
  emitNumbers(10).listen((number){
    print(number);
  });
}
/*
결과:
10
9
8
...
0
*/
Stream<int> emitNumbers(int first) async* {
  for(var i = first; i>=0;i--){
    yield i;
    
    await Future.delayed(Duration(seconds: 1));
  }
}

void main(){
  emitNumbers(10).listen((number){
    print(number);
  });
}

1초마다 실행

짝수홀수 타이머

Stream<int> emitNumbers(int first) async* {
  for(var i = first; i>=0;i--){
    yield i;
    
    await Future.delayed(Duration(seconds: 1));
  }
}

void main(){
  emitNumbers(10).where((number)=>number.isOdd).listen((number){
    print('홀수 타이머| $number');
  });
  emitNumbers(10).where((number)=>number.isEven).listen((number){
    print('짝수 타이머| $number');
  });
}

'TIL' 카테고리의 다른 글

[TIL] 큐&연결리스트  (0) 2024.11.06
[TIL] 리스트 빈도 구하기  (0) 2024.11.05
[TIL] 예외/오류  (0) 2024.11.01
[TIL] 콘솔 쇼핑몰 만들기  (0) 2024.10.31
[TIL] dart 클래스  (0) 2024.10.30