[Flutter] 4. 비동기 프로그래밍

Beanxx·2024년 7월 16일
0

Flutter

목록 보기
4/5
post-thumbnail

✅ Future

delayed() : 실행 지연 함수로, 2개의 파라미터를 가짐

‣ 1번 parameter : 지연할 기간 (얼마나 지연할건지) = Duration
‣ 2번 parameter : 지연 시간이 지난 후 실행할 함수

void main() {
	Future<String> name = Future.value('flutter');
	Future<int> number = Future.value(1);
	Future<bool> isTrue = Future.value(true);
	t
	print('함수 시작');
	
	Future.delayed(Duration(seconds: 2), () {
		print('Delay 끝');
	});
}

// ‣ 함수 시작
// ‣ (2초 뒤에) Delay 끝
void addNumbers(int number1, int number2) {
	print('계산 시작: $number1 + $number2');
	
	// Future -> async
	Future.delayed(Duration(seconds: 2), () {
		print('계산 완료: $number1 + $number2 = ${number1 + number2}');
	});
	
	print('함수 완료');
}

addNumbers(1, 1);
// ‣ 계산 시작: 1 + 1
// ‣ 함수 완료
// ‣ 계산 완료: 1 + 1 = 2

addNumbers(1, 1);
addNumbers(2, 2);
// ‣ 계산 시작: 1 + 1
// ‣ 함수 완료
// ‣ 계산 시작: 2 + 2
// ‣ 함수 완료
// ‣ (2초 후) 계산 완료: 1 + 1 = 2
// ‣ 계산 완료: 2 + 2 = 4

✅ await & async

  • await는 future를 return해주는 함수에만 사용 가능
    🚨 만약 void type를 return하는 함수에 사용시 error
  • await를 통해 return 값을 받을 수도 있음
    🚨 만약 await 쓰지 않으면 return 값을 받지 못함
  • await는 논리적으로 순서대로 실행
    • 기다리는 순간동안 CPU가 놀고 있는게 아니라 다른 작업을 할 수 있음
    • But, 함수 안에서의 코드는 await를 기다리고 다음 로직 실행
// Future 타입 리턴 함수
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;
	
	// ‣ 계산 시작: 1 + 1
	// ‣ 계산 완료: 1 + 1 = 2
	// ‣ 함수 완료: 1 + 1
	
	// ‣ 계산 시작: 1 + 1
	// ‣ 계산 시작: 2 + 2
	// ‣ 계산 완료: 1 + 1 = 2
	// ‣ 함수 완료: 1 + 1
	// ‣ 계산 완료: 2 + 2 = 4
	// ‣ 함수 완료: 2 + 2
}

void main() async {
	final result1 = await addNumbers(1, 1);
	final result2 = await addNumbers(2, 2);
	
	print('result1: $result1'); // result1: 2
	print('result2: $result2'); // result2: 4
}

✅ stream

import 'dart:async';

final controller = StreamController();

final stream = controller.stream; // 1번만 리스닝할 수 있는 리소스 생성
final stream = controller.stream.asBroadcastStream(); // 여러번 리스닝할수 있는 stream 생성 가능

final streamListener1 = stream.where((val) => val % 2 == 0).listen((va) {
	print('Listener 1: $val');
});

final streamListener2 = stream.where((val) => val % 2 == 1).listen((va) {
	print('Listener 2: $val');
});

controller.sink.add(1); 
controller.sink.add(2); 

// ‣ Listener 1: 1
// ‣ Listener 2: 1
// ‣ Listener 1: 2
// ‣ Listener 2: 2

‣ Stream await

yield* (=await): 해당되는 stream에 모든 값을 다 가져올 때까지 기다림

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

Stream<int> playAllStream() async* {
  yield* calculate(1); // 먼저 다 실행된 후 하단 코드 실행
  yield* calculate(1000);
}

// ‣ 0
// ‣ 1
// ‣ 2
// ‣ 3
// ‣ 4

// ‣ 0
// ‣ 1000
// ‣ 2000
// ‣ 3000
// ‣ 4000

// ------------------------------------------

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

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

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

// ‣ calculate(1 : 0)
// ‣ calculate(1 : 1)
// ‣ calculate(1 : 2)
// ‣ calculate(1 : 3)
// ‣ calculate(1 : 4)

// => await
// ‣ calculate(1 : 0)
// ‣ calculate(2 : 0)
// ‣ calculate(1 : 1)
// ‣ calculate(2 : 2)
// ‣ calculate(1 : 2)
// ‣ calculate(2 : 4)
// ‣ calculate(1 : 3)
// ‣ calculate(2 : 6)
// ‣ calculate(1 : 4)
// ‣ calculate(2 : 8)
profile
FE developer

0개의 댓글