getAsync method
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 getAsync await a call to the current caching strategy's
CachingStrategy.onDidGet 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 getAsync that returns a cached value does
not emit this event as the Cache has not updated.
Calls to getAsync are evaluated synchronously and will return the future
value established by the first call to get. This allows calls to
getAsync to return the same value regardless of completion of
asynchronous calls to the current caching strategy's
CachingStrategy.onDidGet method or valueFactory
.
var a = cache.getAsync('id', _superLongAsyncCall);
var b = cache.getAsync('id', _superLongAsyncCall);
var c = cache.getAsync('id', _superLongAsyncCall);
// The futures in this list will all resolve to the same instance,
// which was returned by `_superLongAsyncCall` 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> getAsync(TIdentifier id, Func<Future<TValue>> valueFactory) {
_log.finest('getAsync id: $id');
_throwWhenDisposed('getAsync');
_isReleased[id] = false;
_cachingStrategy.onWillGet(id);
// 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
_cache[id] = valueFactory.call().then((TValue value) async {
await _cachingStrategy.onDidGet(id, value);
_didUpdateController.add(CacheContext(id, value));
return value;
});
return _cache[id]!;
}