個人的には、これまで実装する機会はなかったものの、
他人のコードを読んでいると、時々出くわすので、忘れないための備忘録として記載しておきます。
#AsyncMemoizer
非同期処理を実行して、最初の一回の結果をキャッシュするときに使うもの。
例えば、StateFullWidgetを使用するシチュエーションにおいて、FutureBuilderを入れ込んでデータ取得している場合、
setStateしてリビルドされる度に、FutureBuilderがデータを取得してしまいます。
そういった非同期処理の冗長な再実行を回避させる事ができます。
#使用方法
非常に簡単で、.runOnceの引数に、非同期処理を渡すだけで実装できます。
class _SomeScreenState extends State<SomeScreen>
AsyncMemoizer _memoizer = AsyncMemoizer();
@override
Widget build(BuildContext context) {
return Scaffold(
//省略
child: FutureBuilder(
future: () => async {
return _memoizer.runOnce(() async {
return await getInitData();
});
},
);
//省略
ただし、画面遷移後に、データがキャッシュされていたらまずい様な場合
(再度画面を表示した時は、データを再取得したいような場合)は、
画面遷移後の処理として、要所要所に_memorizerをクリアする処理をいれないといけません。
AsyncMemoizerの使用にあたって
ピンポイントでキャッシュ制御出来て便利そうである一方で、
そのクリア処理等、ちょっと細かな制御が発生する事があるので注意が必要かと思います。
基本的に、以下を守るように実装出来ていれば、あまり出番はないものだと思っています。
- 基本的にStatelessWidgetで実装する。
- StateFullWidgetとする必要がある場合は、最小コンポーネントに切り出して、最下層に追いやる。