Caching futures in Flutter/Dart to improve performance and cost using AsyncCache

There might be cases where some calculation might be happening repeatedly but having stale data is also fine. The example could be reading a file or network response or some cpu intensive calculation.

Dart team have introduced AsyncCache class for the same. According to the docs:

Runs asynchronous functions and caches the result for a period of time.

Let's see this action

import 'package:async/async.dart';

void main() async{
  final sumCache = AsyncCache<int>(const Duration(seconds: 7));

  final result1 = await sumCache.fetch(() => getSum(100));
  print(result1);

  final result2 = await sumCache.fetch(() => getSum(200));
  print(result2);

  await Future.delayed(const Duration(seconds: 10));

  final result3 = await sumCache.fetch(() => getSum(300));
  print(result3);
}

Future<int> getSum(int count) async {
  await Future.delayed(const Duration(seconds: 5));
  return Iterable.generate(count).reduce((value, element) => value + element);
}

The output is

4950
4950
44850

Let decode what happened:

  • final sumCache = AsyncCache<int>(const Duration(seconds: 7)) Here object of AsyncCache class is created with cache expiry duration of seven seconds. The expiry timer starts only after first call to fetch is made. Once the timer expires, the next fetch call with start another expiry timer of same duration.

  • final result1 = await sumCache.fetch(() => getSum(100)) Here fetch method gets called with a callback. This callback will be executed as it is the first time fetch was called.

  • final result2 = await sumCache.fetch(() => getSum(200)) Fetch method was called but the callback will not be executed as cache is still valid.

  • final result3 = await sumCache.fetch(() => getSum(300)) Callback to the fetch method is called and fresh value is assigned to the cache as due to 10 seconds of delay, the timer was expired.

Thanks.