Flutter - Asynchronous programming

kyuu·2021년 8월 17일
0

flutter

목록 보기
2/3

final / const

final 과, const 는 상수를 만드는 제어자(modifier)이다. 두 지시자간의 차이는 언제 초기화 되느냐에 따라 달라지는데, 크게 Runtime에 초기화 되느냐, Compile-time에 초기화 되느냐에 따라 사용이 달라진다.

const는, Compile-time에 초기화 되며, C언어를 예시로 들면 컴파일 과정에서 설정해둔 const 상수가 프로그램 내부에서는 컴파일러가 전부 특정 값으로 미리 변경해둔다.

하지만 final은, Run-time에 결정되어야 하는 상수에 사용한다. 즉, 직접적인 값의 할당 없이 프로그램 자체가 실행되어야 값이 할당 될 수 있을 때가 해당된다. 예를들어, DateTime.now()는 현재 시간을 반환하는 메소드로, 실행 될 당시의 시간을 반환한다. 따라서 Compile 과정에서 값을 알 수 없어 초기화 할 수 없기 때문에 final 지시자를 사용해야 한다.

Isolates and Event loops

Isolate는, dart 내부적으로 단일 스레드 기반의 프로그램이 실행되는 구조이다. 필요에 의해 추가적으로 생성(Isolate.spawn())될 수 있으며, 각 Isolate 는 이름을 보면 알 수 있듯이, 고립된 공간이다. 각 Isolate 는 개별적인 메모리 공간과, 이벤트 루프를 가지고 있어 오래된 이벤트 순으로 순차적으로 일을 수행한다.

Isolate끼리는 메모리를 공유하지 않기 때문에 공유 자원 사용을 위한 문제들을 생각하지 않아도 되며, 메세지를 통해 통신하며, 메시지를 받은 Isolate는 고유의 이벤트 루프 공간에서 이를 처리한다.

ㅅㄷㄴㅅ

Isolate 내부에 있는 Event loop는 본질적으로 비동기 프로그래밍을 수행할 수 있게 하는 도구이다. Future, Stream, async/await와 같은 제어자들도, Event loop를 통해 동작한다.

Future

Future는, 비동기 프로그래밍의 결과를 나타내며, 어떠한 작업 결과물을 나중에 받기로 약속하는 것이다.

결과물의 유/무에 따라 3가지 상태로 나눠진다.

  1. 미완료(Uncompleted) : future 객체 생성 후, 작업을 요청한 상태
  2. 완료(Completed) : 요청한 작업이 완료된 상태
    2.1 data : 정상적인 data 리턴
    2.2 error : 작업 처리 과정 문제 발생으로, 에러 리턴

Future는 흔히 상자로 표현되며, 나중에 상자가 열리게 될 때, 안에 담겨 있는 내용물을 어떻게 해야 하는지 표기하기 위해 사용한다. 이를 위한 도구가 async/await이다.

async/await

비동기 실행 순서를 정해주기위한 규칙은 아래와 같다.

  1. 비동기 함수를 정하기 위해 함수 body에 async를 명시한다.
  2. await키워드는 async로 명시된 비동기 함수 내에서만 동작한다.

아래 코드를 봐보자.

// This example shows how *not* to write asynchronous Dart code.

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

Future<String> fetchUserOrder() =>
    // Imagine that this function is more complex and slow.
    Future.delayed(
      const Duration(seconds: 2),
      () => 'Large Latte',
    );

void main() {
  print(createOrderMessage());
}
// Your order is: Instance of '_Future<String>'

동기적 실행 순서를 보면, 아래와 같다.

  1. main()문에서 createOrderMessage() 함수 실행.
  2. 내부 fetchUserOrder() 실행.
  3. fetchUserOrder()가 비동기 함수이기 때문에 다음줄인 return print문 실행.

이 과정에서, fetchUserOrder() 함수 내부에서 데이터를 가져오는 과정이, 2초의 지연을 가지고 있기 때문에, 먼제 실행되는 return 출력문은 정확한 데이터를 가지고 있지 않은 Future 객체를 출력해 버린다.

이 과정을 방지하기 위해, async/await 제어자 도구를 활용하여 비동기 과정의 정보를 추가한다.


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

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

void main() async{
  print(await createOrderMessage());
}
// Your order is: Instance of Large Latte

출처

  1. 브런치북
profile
!..!

0개의 댓글

관련 채용 정보