Flutter

[Flutter] Future과 FutureBuilder를 이용한 비동기 작업

izongg 2023. 8. 31. 02:34
반응형

'Future'과 'FutureBuilder'은 Flutter에서 비동기 작업을 수행하고, 결과를 UI로 표시하는데 사용되는 개념이다.

먼저 동기와 비동기의 차이에 대해 알아보면,

동기는 서버에 요청을 보냈을 때 응답이 돌아와야 다음 동작을 수행하는 것이고, 비동기는 요청을 보냈을 때 응답이 돌아오는지 여부에 상관없이 다음 동작을 동시에 수행 하는 것이다.

 

그럼 개발 중에 동기와 비동기는 왜 중요할까 ?

예를들어, 서버로부터 대용량의 데이터를 받아와서 화면에 출력해주는 것을 구현한다고 해보자.

Flutter는 기본적으로 동기적인 방식으로 작동하므로, 대용량 데이터를 받아올 때 다른 작업은 중지될 것이다. 그러므로 데이터를 다 받아오기 전까지 사용자 화면에 아무것도 표시되지 않는다.

하지만 비동기 방식을 사용하면, 서버로부터 데이터를 받아오는 동안에도 화면의 다른 부분을 그리는 작업을 동시에 수행할 수 있다.

이를 통해 사용자는 데이터를 기다리는 동안 화면에 다른 내용이 표시되고, 앱이 더 빠르고 반응적으로 느껴진다.

이런 비동기방식을 구현하기 위해 Flutter에서는 Future과 FutureBuilder을 사용한다.

Future은 데이터를 가져오는 과정이고, FutureBuilder은 Future을 통해 가져온 데이터를 화면에 그리는 과정에서 사용한다.

Future

Future은 미래의 값이 들어올 공간을 의미한다. 예를들어 내가 카페에서 아메리카노를 주문한다고 가정하자. 주문을 하고 아메리카노가 만들어지는동안은 아메리카노가 아직 만들어지지 않았기 때문에 Future라고 할 수 있다.

즉 이것을 코드로 하면,
Future<아메리카노>가 현재 아직 받지못한 아메리카노라고 할 수 있고, _makeCoffee() 함수가 아메리카노를 만드는 과정이라고 할 수 있다.
그리고 완성된 아메리카노가 Americano(coffee) 이다.

Future<Americano> createCoffee() async {
  final coffee = await _makeCoffee();
  return Americano(coffee);
}

여기서 궁금한 것이 생길 것이다. async 와 await은 뭘까?

만약 저 코드에서 async와 await이 없다면, 완성되지도 않은 커피를 return값으로 내보낼 것이다.

await을 붙여줌으로써 커피가 만들어지는 시간을 기다려주었다가 완성된 커피를 return해준다.

즉, async와 await은 Future을 더 용이하게 사용할 수 있도록 해준다.

FutureBuilder

FutureBuilder은 Future의 결과를 바탕으로 UI를 업데이트하는 위젯이다.

FutureBuilder의 예시는 이렇다.

FutureBuilder(
    future: createCoffee(),
    builder: (BuildContext context, AsyncSnapshot snapshot) {

        //해당 부분은 data를 불러오는 동안에 실행되는 부분
        if (snapshot.hasData == false) {
        return CircularProgressIndicator(); 
        }
        //error가 발생하게 될 경우 반환하게 되는 부분
        else if (snapshot.hasError) {
        return Padding(
            padding: const EdgeInsets.all(8.0),
            child: Text(
            'Error: ${snapshot.error}', // 에러명을 텍스트에 뿌려줌
            style: TextStyle(fontSize: 15),
            ),
        );
        }
        // 데이터를 정상적으로 받아오고 난 후 실행되는 부분
        else {
        return Padding(
            padding: const EdgeInsets.all(8.0),

            child: Text(
            snapshot.data.toString(), // 비동기 처리를 통해 받은 데이터를 텍스트에 뿌려줌
            style: TextStyle(fontSize: 15),
            ),
        );
        }
    })


future: 에는 Future객체를 넣어 Future을 통해 받아 올 데이터를 입력한다.
builder: Future을 통해 받아온 데이터를 snapshot에 저장한 후, ui에 뿌려주는 역할을 한다.

반응형