🤖

【Flutter】キャッシュ付きFutureProvider

2023/08/30に公開

familyFutureProviderを運用している場合など、特定のキーだけキャッシュをクリアしたい(e.g. この日のデータだけクリアしたい)などの用途が発生したので、備忘録として記載します。

clearCacheForKey,clearCacheも生やして外部からキャッシュクリアできるようにしていますが、動作未検証・未テストです。

追って精査できたらUpdateします。

import 'dart:async';

import 'package:hooks_riverpod/hooks_riverpod.dart';

extension AutoDisposeRefCache on AutoDisposeRef {
  static final Map<String, Timer> _timersMap = {};

  // Keeps the provider alive for [duration] since when it was first created
  void cacheFor(Duration duration, {String? cacheKey}) {
    if (cacheKey != null && _timersMap.containsKey(cacheKey)) {
      _timersMap[cacheKey]!.cancel();
    }

    final link = keepAlive();
    final timer = Timer(duration, () {
      link.close();
      if (cacheKey != null) {
        _timersMap.remove(cacheKey);
      }
    });

    if (cacheKey != null) {
      _timersMap[cacheKey] = timer;
    }

    onDispose(() {
      timer.cancel();
      if (cacheKey != null) {
        _timersMap.remove(cacheKey);
      }
    });
  }

  // Manually clears the cache for a given key
  /// e.g.
  /// AutoDisposeRefCache.clearCacheForKey('some_key');
  static void clearCacheForKey(String key) {
    if (_timersMap.containsKey(key)) {
      _timersMap[key]!.cancel();
      _timersMap.remove(key);
    }
  }

  // Manually clears the cache for this AutoDisposeRef
  /// e.g.
  /// ref.clearCache();
  static void clearCache(AutoDisposeRef ref) {
    // clear all cache for this ref
    _timersMap.forEach((key, timer) {
      if (timer.isActive && timer.tick == 0) {
        timer.cancel();
        _timersMap.remove(key);
      }
    });
  }
}

Refs

Discussion