4 minute read

3장

chapter 03 다트 비동기 프로그램

학습목표 : 다트 언어는 동기/비동기 프로그래밍을 지원.

동기 = 요청하고나서 응답이 올때까지 더는 코드를 진행하지 못하고 기다렸다가 응답을 받으면 그제서야 다음 코드 진행

비동기 = 요청하고나서 응답을 받지 않았는데도 대기하지않고 다음 코드를 진행. 언제든 응답이 오면 즉시 응답을 처리하게 됨.

3.1 동기 vs 비동기 프로그래밍

비동기 프로그래밍은 요청한 결과를 기다리지 않으며 응답 순서 또한 요청한 순서와 다를 수 있음. 더욱 효율적으로 코드를 실행할 수 있음.

IMG_0924

3.2 Future

미래에 받아올 값. List나 Set 처럼 제네릭으로 어떤 미래의 값을 받아올지를 정할 수 있음

Future < String > name; // 미래에 받을 String 값

비동기 프로그래밍은 서버 요청과 같이 오래 걸리는 작업을 기다린 후 값을 받아와야 하기 때문에 미래 값을 표현하는 Future 클래스가 필요합니다.

Future.delayed(Duration(seconds:3) 는 비동기 연산이기 때문에 리소스를 허비하지 않고 다음 코드를 바로 실행함.

CPU가 아무것도 하지 않으며 낭비할 뻔한 시간(3초) 동안 다른 작업을 할 수 있어 더 효율적으로 CPU 리소스 사용

3.3 async, await

그런데 코드가 작성된 순서대로 실행되지 않는다면 개발자 입장에서는 헷갈림.

async, await 키워드를 사용하면 비동기 프로그래밍을 유지하면서도 코드 가독성을 유지할 수 있음.

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

//await는 대기하고싶은 비동기 함수 앞에 입력함.
await Future.delayed(Duration(seconds:3),(){
	print('계산중')
})

함수를 async로 지정하고, 대기하고싶은 비동기 함수를 실행할때 await 키워드를 사용하면 코드는 작성한 순서대로 실행됨.

→ 그럼 이건 동기 프로그래밍 아님?

→ No. async, await 키워드를 사용하면 비동기 프로그래밍 특징을 그대로 유지하며 코드가 작성된 순서대로 프로그램을 실행함.

IMG_0924

여기서 더 addNumbers(1,1), addNumbers(2,2) 가 순차적으로 실행되길 바란다면 async, await 키워드를 추가하면 됨


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

IMG_0924

  • 코드는 작성한 순서대로 실행 되었음.

3.3.1 결과값 반환받기

async, await 키워드를 사용한 함수에서도 결과값 받을 수 있음

final result = await addNumbers(1,1);

3.4 stream

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

Stream은 한번 Listen 하면 Stream 에 주입되는 모든 값들을 지속적으로 받아옴.

Future.wait() 함수는 하나의Future 로 구성된 리스트를 매개변수로 입력받음 Future.wait() 에 입력된 비동기 함수들은 모두 동시에 실행되며 응답값 요청을 보낸 순서대로 정리해둡니다.

3.4.1 스트림 기본 사용법

dart:sync 패키지 불러오기.

StreamController listen()하면 값을 지속적으로 반환 받을 수 있음.

import 'dart:async'

void main(){
	final controller = StreamController();
	final stream = controller.stream;
	// Stream 에 listen() 함수를 실행하면 값이 주입될때마다 콜백함수를 실행할 수 있음.
	final streamListener1 = stream.listen((val{
		print(val);
}

// Stream 에 값을 주입하기
controller.sink.add(1);

3.4.2 브로드캐스트 스트림

스트림은 단 한번만 listen()을 할 수 있는데 때때로 하나의 스트림을 생성하고 여러번 listen() 함수를 실행하고 싶을때, 브로드 캐스트 스트림을 사용하면 스트림을 여러번 listen() 하도록 변환할 수 있음.


final stream = controller.stream.asBroadcastStream();
final streamListener1 = stream.listen((val){
	print('listening 1')
	print(val)
})

final streamListener2 = stream.listen((val){
	print('listening 2')
	print(val)
})

//add() 를 실행할때마다 listen()하는 모든 콜백 함수에 값이 주입됨.
controller.sing.add(1)
// listening1
// 1
// listening 2
// 1

3.4.3 함수로 스트림 반환하기

StreamController 를 직접 사용하지 않고도 직접 스트림을 반환하는 함수를 작성할 수도 있음.

Future를 반환하는 함수는 async로 함수를 선언하고 return 키워드로 값을 반환

Stream을 반환하는 함수는 async*로 함수를 선언하고 yield 키워드로 값을 반환

Updated:

Leave a comment