[TIL] Dart 비동기 프로그래밍

티라노·2024년 11월 6일
0

Today I Learned

목록 보기
14/21

Dart 문법을 사용하여 비동기 프로그래밍 하는 방법을 알아본다.

트러블슈팅이 들어간 TIL은 따로 모으고 싶어서 게시글을 두 개로 나눴다.
과제와 관련된 내용은
https://velog.io/@utiranoj/TIL-RPG-게임2-필수-기능-보충
참조

동기 프로그래밍이란?

프로그래밍을 할 때, 대부분의 코드는 작업을 순차적으로 처리한다.
작업 하나가 끝나서 결과가 나오면 값을 반환하고 다음 줄로 넘어가는 식이다.
이러한 코드를 동기적인 코드라고 부른다.

용량이 크지 않은 동작을 할 때는 동기적으로 프로그래밍해도 명시적인 차이가 보이지 않는다.
그러나 파일을 읽거나 데이터베이스에 접근하는 등 오랜 시간이 걸리는 작업을 할 때는 긴 처리시간동안 아무런 동작도 하지 않고 기다려야 한다는 점이 비효율적으로 느껴질 수 있다.

그래서 존재하는 것이 비동기 프로그래밍이다.

비동기 프로그래밍이란?

비동기적인 코드는 작업이 완료되는 순간이 아닌, 미래의 특정 시점에 값을 반환한다. 그리고 그 동안 수행할 수 있는 다른 작업이 있다면 찾아서 계속 수행한다.

예를 들어서 아래와 같은 코드가 있다고 하자.

// *****
// 비동기 방식으로 file reading 하는 코드
// *****
print('1');

동기 방식에서는 긴 파일을 모두 읽고 난 후에야 '1'이 출력될 것이다.

하지만 비동기 방식에서는 파일 읽기를 시작한 다음 곧바로 1을 출력한다. 그리고 어느 시점에 파일 읽기가 끝나면 해당 값을 반환한다.

Dart와 비동기 프로그래밍

Dart에서도 비동기 프로그래밍을 할 수 있다. 비동기 프로그래밍을 지원하는 클래스는 Future, Stream 으로 dart:async 를 import하여 사용한다.

Future

하나의 작업 당 값 반환이나 이벤트가 한 번 발생하는 단일 비동기 작업에 사용한다.
사용자가 여러 번 써야 하거나 실시간으로 변경을 반영하는 동작에 어울리지 않는다.

비동기 프로그래밍에서 쓰이는 대표적인 클래스이다.

dart:async 의 클래스 중 하나이지만 dart:core 에도 포함되어있기 때문에 따로 SDK를 불러오지 않아도 사용할 수 있다.

Future 클래스에서는 delayed() 메서드를 통해 동작을 지연시킬 수 있다.
매개 변수로 지연할 시간을 전달하고 코드 블록 안에 지연 시간만큼 기다린 후에 처리할 동작을 적으면 된다.
만약 비동기 코드를 동기적인 코드처럼 실행되게 하려면 다음 과정을 거친다.

  1. 비동기적인 코드 앞에 await 추가
  2. await 가 붙은 코드를 포함하는 전체 함수에 async 추가

awaitFuture 류 함수에만 사용할 수 있다. 예를 들어서 void 타입의 함수에 await 를 적용하고 싶으면 반환타입을 Future<void> 로 바꿔야 한다.

하지만 await 를 쓴다고 해서 완전히 동기적인 결과가 나오는 것은 아니다.
await 키워드는 들어간 객체에만 효과를 발휘하기 때문에, 다음에 올 예정인 다른 객체가 있으면 프로그램은 해당 객체를 비동기적으로 먼저 실행한다.

Stream

하나의 작업 당 값 반환이나 이벤트가 여러 번 발생하는 경우에 사용한다.
비동기 연산의 결과값이 여러 번 반환될 때 그 값들을 순차적으로 받기 위해 쓰인다.

Future 와 마찬가지로 비동기 프로그래밍에 쓰이는 클래스이다.

Stream 은 시간에 따라서 연속적인 데이터 흐름을 제공한다. 결과값을 한 번 반환하면 자동으로 실행을 종료하는 Future 와 달리 계속 값을 받고 처리하기 위한 대기 상태에 있다는 의미이다.
따라서 실행 종료 시점을 따로 명시해야 한다.

값을 여러 번 내보내는 것이 주 쓰임새인 만큼 return 대신 yield 키워드로 값을 방출 할 수 있다. 반환과 달리 값을 방출해도 함수가 종료되지 않는다.
이 때 Stream 을 반환 타입으로 갖는 함수에는 async 가 아닌 async* 를 붙여야 한다.

0개의 댓글