Wednesday, March 20, 2024

Flutter에서 async와 async*의 차이점 및 활용 방법

Flutter에서 async와 async*의 개념 소개

Flutter는 Dart라는 언어를 사용하여 앱을 개발합니다. Dart는 비동기 프로그래밍을 지원하는데, 이는 여러 작업을 동시에 처리할 수 있게 해주는 기능입니다. 비동기 프로그래밍에서 중요한 개념 중 하나가 바로 'Future'와 'Stream'입니다. 이 두 개념을 이해하려면 async와 async* 키워드를 알아야 합니다.

async 키워드는 함수가 Future를 반환하도록 만듭니다. Future는 어떤 작업이 완료될 때까지 기다리는 동안 다른 작업을 계속할 수 있게 해주는 객체입니다. 즉, Future는 비동기 작업의 결과를 나타냅니다.

반면에 async* 키워드는 함수가 Stream을 반환하도록 만듭니다. Stream은 시간이 지남에 따라 여러 값을 생성할 수 있는 객체입니다. 즉, Stream은 시간에 따른 비동기 이벤트 시퀀스를 나타냅니다.

이제 async와 async*의 차이점과 각각 어떻게 활용하는지에 대해 자세히 알아보겠습니다.

async와 async*의 차이점

async와 async*는 모두 Dart에서 비동기 프로그래밍을 위한 키워드입니다. 하지만 두 키워드는 서로 다른 방식으로 작동하며, 서로 다른 유형의 객체를 반환합니다.

async 키워드는 Future 객체를 반환하는 함수를 정의하는 데 사용됩니다. 이 Future 객체는 비동기 작업의 결과를 나타내며, 이 작업이 완료될 때까지 기다리는 동안 다른 작업을 계속할 수 있습니다. async 함수 내에서 'await' 키워드를 사용하여 Future가 완료될 때까지 기다릴 수 있습니다.

반면에 async* 키워드는 Stream 객체를 반환하는 함수를 정의하는 데 사용됩니다. Stream 객체는 시간에 따라 여러 값을 생성할 수 있습니다. async* 함수 내에서 'yield' 또는 'yield*' 키워드를 사용하여 Stream에 값을 추가할 수 있습니다.

따라서 async와 async*의 주요 차이점은 반환하는 객체의 유형과 그 객체가 어떻게 사용되는지에 있습니다. async는 단일 값을 반환하는 비동기 작업에 적합하며, async*는 시간에 따라 여러 값을 생성하는 비동기 작업에 적합합니다.

async의 활용 예시

async 키워드는 Future 객체를 반환하는 함수를 정의하는 데 사용됩니다. 이는 비동기 작업의 결과를 나타내며, 이 작업이 완료될 때까지 기다리는 동안 다른 작업을 계속할 수 있습니다. 다음은 async의 활용 예시입니다.

예를 들어, 데이터를 웹에서 가져오는 함수를 생각해봅시다. 이 함수는 데이터를 가져오는 데 시간이 걸리므로, 이를 비동기적으로 처리해야 합니다. 이럴 때 async와 Future를 사용할 수 있습니다.

다음은 async를 사용한 예시 코드입니다.


Future<String> fetchData() async {
  var response = await http.get('https://example.com/data');
  if (response.statusCode == 200) {
    return response.body;
  } else {
    throw Exception('Failed to load data');
  }
}

위의 fetchData 함수는 async 키워드를 사용하여 Future을 반환합니다. 이 함수는 http.get 메서드를 호출하여 웹에서 데이터를 가져옵니다. 이 메서드는 Future를 반환하므로, await 키워드를 사용하여 Future가 완료될 때까지 기다립니다. 그런 다음, 응답의 상태 코드를 확인하여 데이터를 반환하거나 예외를 던집니다.

이렇게 async와 Future를 사용하면 비동기 작업을 쉽게 처리할 수 있습니다.

async*의 활용 예시

async* 키워드는 Stream 객체를 반환하는 함수를 정의하는 데 사용됩니다. Stream 객체는 시간에 따라 여러 값을 생성할 수 있습니다. 다음은 async*의 활용 예시입니다.

예를 들어, 일정 시간 간격으로 값을 생성하는 함수를 생각해봅시다. 이 함수는 시간이 지남에 따라 값을 생성하므로, 이를 비동기적으로 처리해야 합니다. 이럴 때 async*와 Stream을 사용할 수 있습니다.

다음은 async*를 사용한 예시 코드입니다.


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

위의 countStream 함수는 async* 키워드를 사용하여 Stream을 반환합니다. 이 함수는 1초마다 숫자를 생성하고, 이를 Stream에 추가합니다. 이는 'yield' 키워드를 사용하여 수행됩니다.

이렇게 async*와 Stream을 사용하면 시간에 따라 여러 값을 생성하는 비동기 작업을 쉽게 처리할 수 있습니다.

async와 async*를 함께 사용하는 경우

async와 async*는 각각 다른 유형의 비동기 작업에 적합하지만, 때로는 두 키워드를 함께 사용해야 하는 경우도 있습니다. 이는 특히 Stream에서 데이터를 가져오고, 이를 처리하는 데 시간이 걸리는 경우에 해당합니다.

예를 들어, 웹에서 데이터를 스트리밍하고, 각 데이터 항목을 처리하는 함수를 생각해봅시다. 이 함수는 데이터를 가져오는 데 시간이 걸리므로, 이를 비동기적으로 처리해야 합니다. 또한, 각 데이터 항목을 처리하는 데도 시간이 걸리므로, 이 역시 비동기적으로 처리해야 합니다. 이럴 때 async와 async*를 함께 사용할 수 있습니다.

다음은 async와 async*를 함께 사용한 예시 코드입니다.


Stream<Data> processData(Stream<String> rawData) async* {
  await for (var data in rawData) {
    var processedData = await process(data);
    yield processedData;
  }
}

위의 processData 함수는 async* 키워드를 사용하여 Stream을 반환합니다. 이 함수는 rawData 스트림에서 데이터를 가져오고, 이를 처리합니다. 이는 'await for' 루프를 사용하여 수행됩니다. 그런 다음, 처리된 데이터를 Stream에 추가합니다. 이는 'yield' 키워드를 사용하여 수행됩니다.

이렇게 async와 async*를 함께 사용하면, 시간에 따라 여러 값을 생성하고, 각 값을 비동기적으로 처리하는 복잡한 작업을 쉽게 처리할 수 있습니다.

결론

이 글에서는 Flutter에서 async와 async*의 차이점과 활용법에 대해 알아보았습니다. async는 Future 객체를 반환하며, 단일 값을 반환하는 비동기 작업에 적합합니다. 반면에 async*는 Stream 객체를 반환하며, 시간에 따라 여러 값을 생성하는 비동기 작업에 적합합니다.

또한, async와 async*를 함께 사용하여 시간에 따라 여러 값을 생성하고, 각 값을 비동기적으로 처리하는 복잡한 작업을 쉽게 처리할 수 있음을 알아보았습니다.


0 개의 댓글:

Post a Comment