get method

  1. @mustCallSuper
Future<TValue> get(
  1. TIdentifier id,
  2. Func<TValue> valueFactory
)

Returns a value from the cache for a given TIdentifier.

If the TIdentifier is not present in the cache the value returned by the given valueFactory is added to the cache and returned.

All calls to get await a call to the current caching strategy's CachingStrategy.onDidGet lifecycle method before returning the cached value. If the Cache does not contain an instance for the given TIdentifier, the given valueFactory is called and a CacheContext event is emitted on the didUpdate stream. A call to get that returns a cached value does not emit this event as the Cache has not changed.

Calls to get are evaluated synchronously and will return the future value established by the first call to get. This allows calls to get to return the same value regardless of completion of asynchronous calls to the current caching strategy's CachingStrategy.onDidGet lifecycle method or valueFactory.

var a = cache.get('id', _superLongCall);
var b = cache.get('id', _superLongCall);
var c = cache.get('id', _superLongCall);

// The futures in this list will all resolve to the same instance,
// which was returned by `_superLongCall` the first time `get` was called.
var values = Future.wait([a, b, c]);

If the Cache isOrWillBeDisposed then a StateError is thrown.

Implementation

@mustCallSuper
Future<TValue> get(TIdentifier id, Func<TValue> valueFactory) {
  _log.finest('get id: $id');
  _throwWhenDisposed('get');
  _cachingStrategy.onWillGet(id);
  _isReleased[id] = false;
  // Await any pending cached futures
  if (_cache.containsKey(id)) {
    return _cache[id]!.then((TValue value) async {
      await _cachingStrategy.onDidGet(id, value);
      return value;
    });
  }

  // Install Future value
  final Completer<TValue> completer = Completer<TValue>();
  _cache[id] = completer.future;
  try {
    final TValue value = valueFactory.call();

    _cachingStrategy.onDidGet(id, value).then((Null _) {
      _didUpdateController.add(CacheContext(id, value));
      completer.complete(value);
    });
  } catch (error, stackTrace) {
    completer.completeError(error, stackTrace);
  }

  return _cache[id]!;
}