Future-async 심화학습 - 1

JohnKim·2022년 8월 17일
0

flutter

목록 보기
6/7

Thread

프로세스내에서 실행되는 흐름의 단위

process vs. program

포토샵 프로그램은 사용자가 실행했을때만 작동하는 하나의 데이터 묶음일 뿐이다.
사용자가 더블클릭해서 포토샵을 실행시킨다면 메모리에 등록이 되고 실제 작동하는 하나의 프로세스가 된다.

실행중 => 프로세스
실행전 => 프로그램

Dart는 싱글 스레드로 운영되는 언어

한번에 오직 하나의 작업만을 실행하며 이 작업이 실행되는 동안 다른 작업이 개입될 여지가 없다
그렇다면 여러 작업을 어떻게 처리할까?

Event loop

  1. First In First Out(FIFO) 방식으로 Micro Task와 Event 준비
  2. main 함수 실행
  3. Event loop 실행

Future

  1. Dart에 의해서 future 객체가 내부적인 배열에 등록
  2. Future 관련해서 실행되어야 하는 코드들이 이벤트 큐(대기열)에 등록
  3. 불완전한 future 객체가 반환 (현물로 바꾸지 않은 영수증 처럼)
  4. Synchronous 방식으로 실행되어야 할 코드 먼저 실행
  5. 최종적으로 실제적인 data값이 future 객체로 전달

다음에서 출력되는 순서는 어떻게 될까?

void main(){
  print('Before the Future');
  Future((){
    print('Running the Future');
  }).then((_){
    print('Future is complete');
  });
  print('After the Future);
}

Before the Future 출력 => Future 코드인 print()를 이벤트큐에 등록, then()은 이벤트큐에 등록되지 않는다. =>
After the Future 출력, syncronous 방식으로 실행되는 코드 끝 => Future 출력 => then 출력

Async method

  1. dart는 async키워드를 사용하는 순간 이 메서드를 통해서 나오는 결과물은 future라는것을 알게된다.
  2. Await 키워드를 만날때까지 동기방식으로 코드처리
  3. await 키워드를 만나면 future가 완료될 때까지 대기
  4. future가 완료되자마자 그 다음 코드들을 실행

어떨때 future를 써야하고 async를 구분해서 써야하는가?

String createOrderMessage(){
  var order = fetchUserOrder();
  return 'Your order is: $order';
}

Future<String> fetchUserOrder(){
  return Future.delayed(
    Duration(seconds: 2),
    () => 'Large Latte',
   );
}

void main(){
  print('Fetching user order...');
  print(createOrderMessage());
}

Console

Fetching user order...
Your order is: Instance of '_future<String>'

이렇게 출력되는 이유는 duration에 2초를 기다려야 하는데 이 값이 바로 return값에 할당되기 때문이다.
이 문제를 해결하기위해서 필요한것이 async 키워드이다.

createOrderMessage의 return 값은 비동기 값으로 실행한 결과의 String 값을 return 시켜줘야 하므로 타입을 Future(String)으로 바꾸어야만 한다.

그리고 fetchUserOrder 함수에 리턴값을 할당해주려면 그 즉시 할당하는 syncronous 방식이 아니라 기다렸다가 할당하는 방식이기 때문에 async를 붙여준다.

이제 fetchUserOrder 함수에 실행이 끝날때까지 기다렸다가 order 변수에 값을 할당해줘야 하므로 fetchUserOder()앞에 await 키워드를 붙여준다.

main()에서 호출되는 createOrderMessage() 메서드가 비동기 방식으로 처리되는 함수이므로 main()도 비동기 방식으로 되기때문에 main()에도 async를 붙여준다.

createOrderMessage()가 출력되려면 order 변수에 값이 할당될때까지 기다려야 하므로 await를 붙여준다.

정리

async 키워드는 Future 자체를 대신하는 것이 아니라 비동기 방식으로 실행되는 함수라는 것을 dart에게 알려주는 것이며,
await 키워드와 함께 미래에 전달될 값을 알려주는 것이다.

Future<String> createOrderMessage() async {
  var order = await fetchUserOrder();
  return 'Your order is: $order';
}

Future<String> fetchUserOrder() {
  return Future.delayed(
    Duration(seconds: 2),
    () => 'Large Latte',
  );
}

void main() async {
  print('Fetching user order...');
  print(await createOrderMessage());
}


// Console
// Fetching user order...
// Your order is: Large Latte
profile
Developer

0개의 댓글