본문 바로가기
  • 포르쉐타고싶다
인포테인먼트 - development/flutter

[flutter] Future, 그리고 async await

by 지오ㄴl 2020. 6. 18.

Flutter를 시작한 지 얼마되지 않은 개발자분들 중

필자같이 Future와 async await의 관계 혹은 차이에 대해 헷갈리는 분들이 있을 수 있다.

그 관계, 그리고 차이에 대해 예제와 함께 알아보겠다.

 

핵심은 다음과 같다

1. Future함수, async함수들을 모두 await하지 않았을 때
2. Future함수를 await!
3. async함수를 await!
4. Future함수를 갖고있는 변수의 Type결정(Future<T>형 vs T형)

 

기본적으로 사용하는 예제는 다음과 같다

void main() {
  print('Main program: Starts');

  printFileContent();

  print('Main program: Ends');
}

printFileContent() {

  Future<String> fileContent = downLoadAFile();
  print('The content of the file is --> $fileContent');

}

Future<String> downLoadAFile() {
  Future<String> result = Future.delayed(Duration(seconds: 5), () {
    return 'My secret file content';
  });

  return result;
}

 

1. Future 함수들을 모두 await하지 않을 때.
import 'package:flutter/material.dart';


/**
 * 1. printFileContent의 fileContent는 Future박스를 갖고있지만ㅇ
 * Future가 await이 없어
 * 모두 진행될 때 까지를 기다리지 않기 때문에, 즉
 * Future의 결과가 열리기 전의 상태, 박스가 열리기 전의 상태를 지니고있기 때문에
 * Future<String>타입의 인스턴스형식을 띄고 있다.
 * Future<T> 함수는 호출되었을 때
 * 1) await으로 호출된다면 T타입
 * 2) await없이 호출된다면 Future<T> 타입으로 return된다.
 *
 *
 * 이 상태로 실행된다면
 * 2. main에서 printFileContent를 호출했을 때
 * 그 순간에 바라본 printFileContent의 fileContent는 마찬가지로 아직상 Future박스에서
 * 개봉되기 전 상태, Future<String>타입, 그 안에서도 값이 정해지지 않은 상태이기 때문에
 * 'Instance of Future<String>'형태로 표현되고 있는 것이다.
 *
 * 3. 이 순간에서부터 main은 printFileContent()가 await이 없기 때문에,
 * 이 함수가 끝날 때까지 기다리지 않고
 * 바로 다음 코드(print)를 호출하게 된다.
 *
 * 4. 그렇다면 두가지의 future 중 printFilecontent에서 호출하고 있는,
 * 나머지 하나의 Future은 어떻게 되는 것일까
 *
 * 마찬가지로 그 printFileContent안에서 그 Future을 호출할 때
 * await를 쓰지 않아서, 기다리지 않기 때문에
 * 기다린 결과를 가져오지 않는 것이다.
 */

/**
 * 결과
 * flutter: Main program: Starts
    flutter: The content of the file is --> Instance of 'Future<String>'
    flutter: Main program: Ends​
 */
 
void main() {
  print('Main program: Starts');

  printFileContent();

  print('Main program: Ends');
}

printFileContent() {

  Future<String> fileContent = downLoadAFile();
  print('The content of the file is --> $fileContent');

}

Future<String> downLoadAFile() {
  Future<String> result = Future.delayed(Duration(seconds: 5), () {
    return 'My secret file content';
  });

  return result;
}

 

2. Future함수를 호출하는 함수에서 await으로 해당 Future을 받을 때
import 'package:flutter/material.dart';


/**
 * --printFilecontent에 async를 적용하여
 * downLoadAFile을 호출할 때 await를 사용하였다.
 *
 * 1. printFileContent의 fileContent를 await하게 호출하
 * 모두 진행될 때 까지를 기다린다.
 * Future의 결과가 열린 후, 즉 박스가 열린 후의 안에 있는 선물을 return하고 있기 때문에
 * 선물의 타입인 String타입을 띄고 있다.
 * 따라서 호출한 함수의 리턴값을 저장하는 fileContent의 타입도 String으로 고쳐준다.
 * Future<T> 함수는 호출되었을 때
 * 1) await으로 호출된다면 T타입
 * 2) await없이 호출된다면 Future<T> 타입으로 return된다.
 *
 *
 * 이 상태로 실행된다면
 * 2. main에서 printFileContent를 호출했을 때
 * 그 순간에 바라본 printFileContent의 fileContent는 Future박스에서
 * 개봉 후 상태, String타입, 그 값으로 표현되고 있는 것이다.
 *
 * 3. 이 순간에서부터 main은 printFileContent()가 await이 없기 때문에,
 * 이 함수가 끝날 때까지 기다리지 않고
 * 바로 다음 코드(print)를 호출한다.
 *
 * 그렇다면 두가지의 future 중 printFilecontent에서 호출하고 있는,
 * 나머지 하나의 Future은 어떻게 되는 것일까
 *
 * 4. printFileContent안에서 그 Future을 호출할 때
 * await을 사용했기 때문에,
 * 기다렸다가 나중에 해당 명령을 실행시킨다.
 */

/**
 * 결과
 * flutter: Main program: Starts
    flutter: Main program: Ends
    flutter: The content of the file is --> My secret file content
 */

void main() {
  print('Main program: Starts');

  printFileContent();

  print('Main program: Ends');
}

printFileContent() async{

  String fileContent = await downLoadAFile();
  print('The content of the file is --> $fileContent');

}

Future<String> downLoadAFile() {
  Future<String> result = Future.delayed(Duration(seconds: 5), () {
    return 'My secret file content';
  });

  return result;
}

 

 

3. Future함수를 호출하고 있는 함수에서도 await하여 해당 Future을 받고,
'main()에서도' Future함수를 호출하고 있는 함수를 await하여 받을 때
import 'package:flutter/material.dart';


/**
 * --main()과 printFilecontent에 모두 async를 적용하여
 * printFileContent와 downLoadAFile을 호출할 때 await를 사용하였다.
 *
 * 1. printFileContent의 fileContent를 await하게 호출하
 * 모두 진행될 때 까지를 기다린다.
 * Future의 결과가 열린 후, 즉 박스가 열린 후의 안에 있는 선물을 return하고 있기 때문에
 * 선물의 타입인 String타입을 띄고 있다.
 * 따라서 호출한 함수의 리턴값을 저장하는 fileContent의 타입도 String으로 고쳐준다.
 * Future<T> 함수는 호출되었을 때
 * 1) await으로 호출된다면 T타입
 * 2) await없이 호출된다면 Future<T> 타입으로 return된다.
 *
 *
 * 이 상태로 실행된다면
 * 2. main에서 printFileContent를 호출했을 때
 * 그 순간에 바라본 printFileContent의 fileContent는 Future박스에서
 * 개봉 후 상태, String타입, 그 값으로 표현되고 있는 것이다.
 *
 * 3. 이 순간에서부터 main은 printFileContent()가 await하고있기 때문에
 * 이 함수가 끝날 때까지 기다렸다가
 * 해당 함수의 명령어를 모두 처리하는것을 기다린 뒤,
 * 다음 코드(print)를 호출한다.
 *
 * 그렇다면 두가지의 future 중 printFilecontent에서 호출하고 있는,
 * 나머지 하나의 Future은 어떻게 되는 것일까
 *
 * 4. printFileContent안에서 그 Future을 호출할 때
 * await을 사용했기 때문에,
 * 기다렸다가 나중에 해당 명령을 실행시킨다.
 */

/**
 * 결과
 * flutter: Main program: Starts
 *
 * (5초뒤)
    flutter: The content of the file is --> My secret file content
    flutter: Main program: Ends
 */
 
void main() async{
  print('Main program: Starts');

  await printFileContent();

  print('Main program: Ends');
}

printFileContent() async{

  String fileContent = await downLoadAFile();
  print('The content of the file is --> $fileContent');

}

Future<String> downLoadAFile() {
  Future<String> result = Future.delayed(Duration(seconds: 5), () {
    return 'My secret file content';
  });

  return result;
}

 

 

위의 예제를 통해 위의 개념들을 확실하게 다지는데 도움이 되었음 좋겠다.

반응형

댓글