새소식

반응형
App/Dart

[Dart] Asynchronous programming(비동기 프로그래밍): futures, async, await (w.Flutter)

  • -
반응형

2023-10-25


사진: Unsplash 의 The Cleveland Museum of Art


1. Asynchronous programming(비동기 프로그래밍)

 

비동기 작업을 통해 프로그램은 다른 작업이 완료되기를 기다리는 동안 작업을 완료하는 것을 의미하며,  다음은 몇 가지 일반적인 비동기 작업의 예제이다.

  • Fetching data over a network.(데이터를 가져올 경우)
  • Writing to a database. (DB 데이터를 기록할 경우)
  • Reading data from a file. (파일에서 데이터를 읽을 경우)
  • . . .

2. 예제_1 [ async와 await  ]

 

우선적으로는 아래는 잘못된 비동기 함수의 호출 예제이다. 다트패드에서 해당 코드를 복사 후 실행을 해보면 실제 2초의 딜레이 없이 바로 출력값이 나오는 것을 확인할 수 있다.

 

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

Future<String> fetchUserOrder() =>
    // Imagine that this function is more complex and slow.
    Future.delayed( //임의로 2초의 시간을 딜레이 시킨다.
      const Duration(seconds: 2),
      () => 'Large Latte',
    );

void main() {
  print("before createOrderMessage()");
  print(createOrderMessage());
  print("after createOrderMessage()");
}

 

 

심지어 출력하는 데이터도 이상하게 나온다. 우리가 원하는 출력값은 Your order is: Large Latte 인데 Your order is: Instance of '_Future <String>' 인스턴스 정보가 출력되고 있다.

 

before createOrderMessage()
Your order is: Instance of '_Future<String>'
after createOrderMessage()

이와 같은 문제가 발생하는 이유는 사용자의 주문을 받으려면 createOrderMessage()fetchUserOrder()를 호출하고 완료될 때까지 기다려야 한다. 그런데 createOrderMessage() fetchUserOrder()가 완료될 때까지 기다리지 않기 때문에 createOrderMessage() fetchUserOrder()가 결국 제공하는 문자열 값을 가져오는 데 실패하게 되는 것이다. Large Latte  값이 실제 딜레이 후 할당되기 전에 값을 가져오기 때문에  Your order is: Instance of '_Future <String>'와 같은 결과가 나오는 것이다.


2. 예제_1 [ async와 await  문제해결]

 

해당 코드의 문제를 해결하기 위해서는 async 와 await 키워드를 활요하는 것이다. async 가 선언된 함수는 await 키워드를 사용할 수 있으며, await 선언된 동작을 해당 동작이 마무리되기까지 다음 동작으로 넘어가지 않고 기다려 준다. 아래는 해결 코드이다.

 

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

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

void main() async {
  print("before createOrderMessage()");
  print(await createOrderMessage());
  print("after createOrderMessage()");
}

 

위의 코드를  다트패드에서 실행해 보면 아래와 같이 기대한 결과가 나오는 것을 확인할 수 있다.

 

before createOrderMessage()
Your order is: Large Latte
after createOrderMessage()

3. Future

 

Future는 자바스크립트의 Promise 비슷한 기능을 하는 키워드이다. 해당 키워드는 비동기 함수의 결과값을 받아주는 기능을 한다. 비동기 함수가 마무리되면 해당 함수의 결과값 또는 에러가 담겨 핸들링을 할 수 있다.


4. 예제_2 [ Future ]

 

아래는 future의 사용 예제이다. 간단히 유저데이터를 가져오는 코드인데, fetchUserOrder 함수는 2초의 딜레이가 있기 때문에 실제 print('After fetching user order...'); 가 먼저 호출된 후 Fetched user order: John Doe, 25  출력되게 된다.

 

class User {
  String name;
  int age;

  User({required this.name, required this.age});
}

Future<User> fetchUserOrder() {
  // Imagine that this function is fetching user info from another service or database.
  return Future.delayed(
    const Duration(seconds: 2),
    () {
      var defaultUser = User(name: 'John Doe', age: 25);
      print('Fetched user order: ${defaultUser.name}, ${defaultUser.age}');
      return defaultUser;
    },
  );
}

void main(){
  fetchUserOrder();
  print('After fetching user order...');
}

5. 출처

https://dart.dev/codelabs/async-await

 

Asynchronous programming: futures, async, await

Learn about and practice writing asynchronous code in DartPad!

dart.dev


메인 이미지 출처 :  사진: UnsplashThe Cleveland Museum of Art

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.