Landroid

FutureBuilder에서 future 함수 중복 호출 방지 본문

플러터

FutureBuilder에서 future 함수 중복 호출 방지

silso 2021. 2. 21. 17:03

Future 함수를 Future Builder를 통해 호출하시는 경우가 있습니다.

하지만 정작 실행해보면 함수에서 호출될 값까지 가져오기 까지 여러번 호출되는 것을 보실 수 있습니다.

이는 자원 낭비로 이어질 수 있기 때문에

가능하면 해결하시는 것이 좋습니다.

 

Future Builder에서 함수를 중복 호출 방지하는 방법이 2가지 있습니다.

하나는 initState로 Future 함수를 변수에 저장하는 방법입니다.

class FutureSample extends StatefulWidget {
  // Create instance variable
  @override
  _FutureSampleState createState() => _FutureSampleState();
}

class _FutureSampleState extends State<FutureSample> {
  Future myFuture;

  Future<String> _fetchData() async {
    await Future.delayed(Duration(seconds: 10));
    return 'DATA';
  }

  @override
  void initState() {
    // assign this variable your Future
    myFuture = _fetchData();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: FutureBuilder(
          future: myFuture,
          builder: (ctx, snapshot) {
            if (snapshot.hasData) {
             return Text(snapshot.data.toString());
            }
            return CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}

 

두번째 방법은 AsyncMemoizer를 사용하는 방법입니다.

 

async | Dart Package

Utility functions and classes related to the 'dart:async' library.

pub.dev

class MemoizerSample extends StatefulWidget {
  @override
  _MemoizerSampleState createState() => _MemoizerSampleState();
}

class _MemoizerSampleState extends State<MemoizerSample> {
  AsyncMemoizer _memoizer;

  _fetchData() async {
    return this._memoizer.runOnce(() async { // This below code will call only ones. This will return the same data directly without performing any Future task.
      await Future.delayed(Duration(seconds: 10));
      return 'DATA';
    });
  }

  @override
  void initState() {
    super.initState();
    _memoizer = AsyncMemoizer();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: FutureBuilder(
          future: _fetchData(),
          builder: (ctx, snapshot) {
            if (snapshot.hasData) {
              return Text(snapshot.data.toString());
            }
            return CircularProgressIndicator();
          },
        ),
      ),
    );
  }
}

 

이와 관련된 영상도 있으니 참고하시길

Comments