<Flutter> Future와 Stream

반응형

Flutter에서 Future와 Stream은 비동기 프로그래밍을 수행하는 두 가지 방법이다.

비동기 프로그래밍은 애플리케이션에서 길게 걸리는 작업을 별도의 쓰레드에서 실행하여 UI의 응답성을 유지하도록 돕는다.

 

Future

Future는 한 번 실행된 후, 값을 반환하거나 에러를 발생시키는 단일 작업이다.

데이터가 처리되면 Future는 완료(completed) 상태가 됩니다.

 

예제: Future를 사용하고 ListView에 데이터를 표시합니다.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  Future<List<String>> _fetchData() async {
    // 대기 상태에 있는 외부 데이터를 시뮬레이션합니다.
    await Future.delayed(Duration(seconds: 2));
    return List<String>.generate(100, (index) => 'Item $index');
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Future Example')),
        body: FutureBuilder<List<String>>(
          future: _fetchData(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Center(child: CircularProgressIndicator());
            } else if (snapshot.hasError) {
              return Center(child: Text('Error occurred'));
            } else {
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (context, index) {
                  return ListTile(title: Text(snapshot.data[index]));
                },
              );
            }
          },
        ),
      ),
    );
  }
}

Stream

Stream은 시간이 지남에 따라 여러 개의 이벤트를 만들어내는 연속적인 작업이다.

Stream은 값을 가져오거나 에러를 발생시킬 수 있으며, 스트림의 마지막 이벤트를 얻은 후 종료된다.

 

예제: Stream을 사용하여 ListView에 데이터를 표시합니다.

import 'package:flutter/material.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  Stream<List<String>> _fetchData() async* {
    for (int i = 0; i < 5; i++) {
      // 대기 상태에 있는 외부 데이터를 시뮬레이션합니다.
      await Future.delayed(Duration(seconds: 1));
      yield List<String>.generate(20 * (i + 1), (index) => 'Item $index');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Stream Example')),
        body: StreamBuilder<List<String>>(
          stream: _fetchData(),
          builder: (context, snapshot) {
            if (snapshot.connectionState == ConnectionState.waiting) {
              return Center(child: CircularProgressIndicator());
            } else if (snapshot.hasError) {
              return Center(child: Text('Error occurred'));
            } else {
              return ListView.builder(
                itemCount: snapshot.data.length,
                itemBuilder: (context, index) {
                  return ListTile(title: Text(snapshot.data[index]));
                },
              );
            }
          },
        ),
      ),
    );
  }
}

차이점:

  • Future는 단일 값을 반환하는 반면에 Stream은 시간에 따라 여러 값을 반환할 수 있다.
  • ListView의 경우, Future는 한번만 값이 변경되어 UI를 업데이트하지만, Stream은 여러 이벤트에 따라 무언가 변경될 때마다 ListView를 업데이트한다.
  • Future는 값을 반환하거나 완료된 상태가 되면 더 이상 사용할 수 없지만, Stream은 계속해서 새로운 값을 들어올 수 있도록 돕는다.

그럼에도 불구하고 ListView에 데이터를 표시하는 데 있어서는 Future와 Stream 모두 사용할 수 있다. 사용 사례에 따라 Future 또는 Stream을 선택하면 된다. 예를 들어 한 번만 데이터를 로드하려는 경우는 Future를 사용하고, 실시간으로 데이터를 업데이트하여 반영하려면 Stream을 사용하면 좋다.

Designed by JB FACTORY