Dart Async programing - Future, await

2022. 6. 23. 22:01DEV/Dart

반응형

Future<T> class Null safety

비동기식 연산의 결과이다.
The result of an asynchronous computation.

시작하고 바로 결과값을 반환 또는 발생시키는 동기식 연산과 달리, 비동기식 연산은 연산이 시작되고 즉시 결과값을 얻지 못한다. 비동기식 연산은 파일을 읽거나 데이터베이스를 읽거나 웹 페이지를 가져오는 등의 시간이 걸리는 외부의 어떤 프로그램을 기다려야 할 때가 있다. 비동기식 연산은 결과를 사용할 수 있을 때까지 모든 연산을 막기보다는 결국에는 결과가 완료될 Future를 즉시 반환한다.
An asynchronous computation cannot provide a result immediately when it is started, unlike a synchronous computation which does compute a result immediately by either returning a value or by throwing. An asynchronous computation may need to wait for something external to the program (reading a file, querying a database, fetching a web page) which takes time. Instead of blocking all computation until the result is available, the asynchronous computation immediately returns a Future which will eventually "complete" with the result.

// Future : 미래에 받을 값
Future<String> name = Future.value('Dart');
Future<int> number = Future.value(1);

쉽게 이해하기 위해 편지를 담아 묻어둔 타입캡슐을 예로 생각해보자. 편지가 담긴 타임캡슐이 Future이고, 나중에 꺼내 열었을 때 타입캡슐 안에 담긴 편지가 결과값(return value)이라고 생각하면 될 듯하다.

 

간단하게 이런 비동기식 프로그래밍의 예를 들어 보자면

  1. 함수1 : 데이터 베이스에 저장된 값을 읽어온다.
  2. 함수2 : 웹 페이지에 표를 만들어 함수1에서 읽어온 데이터를 보여준다.

이런 경우에 함수1에서 데이터를 가져오는 게 끝나지 않은 상태에서 함수2가 실행되면 제대로 된 페이지를 만들 수가 없다. 그래서 이럴 때 비동기식으로 프로그래밍을 해서 완전히 데이터를 받은 다음 다른 함수를 실행시키도록 한다.

sync/async

Future.delayed()

Future.delayed()를 이용해 일정 시간 후에 특정 함수를 실행시킬 수 있다. 이를 통해 async/sync 연산의 흐름을 알아보자.

Future.delayed(Duration, Functon)

delay 함수는 두 개의 파라미터를 받는다.

  1. Duration : 지연시킬 시간값을 가진 클래스
  2. Function : 지정한 시간 후 실행시킬 함수

sync/async 연산 비교

별다른 설정을 하지 않은 기본 sync 연산의 출력값의 순서를 살펴보자.

void main() {
  addNumber(1, 1);
}

void addNumber(int x, int y) {
  print('$x-A. Start');

  Future.delayed(Duration(seconds: 2), () {
    print('$x-B. Caluating');
  });

  print('$x-C. Finish');
}
=>
1-A. Start
1-B. Caluating    // B에서 시간이 걸리는 동안 C가 먼저 실행된다
1-C. Finish        // 지정한 2초의 시간이 지난 뒤 마지막에 실행된다

이제 비동기식 연산으로 설정해보자.

void main() {
  addNumber(1, 1);
}

void addNumber(int x, int y) async {
  print('$x-A. Start');

  await Future.delayed(Duration(seconds: 2), () {
    print('$x-B. Caluating');
  });

  print('$x-C. Finish');
}
=>
1-A. Start
1-B. Caluating    // await를 설정해서 해당 연산이 완료될 때까지 다른 연산의 처리는 중단됨
1-C. Finish        // B가 완료된 후 C가 실행된다

💡async/await
비동기식 연산으로 설정할 때는 함수의 바디 앞에 async를 추가하고 비동기화 시킬 구간에 await를 추가해주면 된다.

함수를 두 번 호출했을 때 연산의 흐름을 살펴보자

void main() {
  addNumber(1, 1); // 함수1
  addNumber(2, 2); // 함수2
}

void addNumber(int x, int y) async {
  print('$x-A. Start');

  await Future.delayed(Duration(seconds: 2), () {
    print('$x-B. Caluating');
  });

  print('$x-C. Finish');
}

=>
1-A. Start        // 함수1-A 실행 후 1-B에서 2초를 대기하는 동안
2-A. Start        // 함수2-A가 시작되고 2-B에서 2초 대기 시작
1-B. Caluating    // 2초 후 함수1의 B가 완료되고
1-C. Finish        // 함수 1의 C가 바로 실행된다
2-B. Caluating    // 2초 후 2-B 완료되고
2-C. Finish        // 바로 2-C가 실행된다.

이제는 함수 자체를 async로 설정해서 비교해보자.

void main() async {
  await addNumber(1, 1); // 함수1
  await addNumber(2, 2); // 함수2
}

Future<void> addNumber(int x, int y) async {
  print('$x-A. Start');

  await Future.delayed(Duration(seconds: 2), () {
    print('$x-B. Caluating');
  });

  print('$x-C. Finish');
}
=>
1-A. Start
1-B. Caluating
1-C. Finish
2-A. Start
2-B. Caluating
2-C. Finish

이제는 모든 게 코드에 작성된 순서대로 진행이 되는 것을 확인할 수 있다.

💡async/await
addNumber 함수를 비동기화 할 때와 마찬가지로 main 함수의 바디 앞에 async를 추가하고 비동기화 시킬 addNumber 함수 앞에 await를 추가해주면 된다.

Future return value

마지막으로 Future의 결과값을 받아보자.

void main() async {
  int rs1 = await addNumber(1, 1); // 함수1
  int rs2 = await addNumber(2, 2); // 함수2
  print('result1 : $rs1');
  print('result2 : $rs2');
}

Future<int> addNumber(int x, int y) async {
  print('$x-A. Start');

  await Future.delayed(Duration(seconds: 2), () {
    print('$x-B. Caluating');
  });

  print('$x-C. Finish');

  return x + y;
}
=>
1-A. Start
1-B. Caluating
1-C. Finish
2-A. Start
2-B. Caluating
2-C. Finish
result1 : 2
result2 : 4

너무나 간단하게도 함수의 Future<T>에 return type을 설정해주면 된다.

REFERNECE
Dart Async
Asynchrony support
Future class
Asynchronous programming: futures, async, await

반응형

'DEV > Dart' 카테고리의 다른 글

Dart Async programming - Stream  (0) 2022.06.24
Dart의 형변환 - List, Map, Set  (0) 2022.06.22
Dart의 함수를 알아보자  (0) 2022.06.22
Dart - Null safety & Dart Codelab Exercise  (0) 2022.06.21
Dart 시작하기 - 구조 및 변수  (0) 2022.06.21