executeStream method

Stream<RxResult<T>> executeStream()

Implementation

Stream<RxResult<T>> executeStream() async* {
  if (TextUtil.isEmpty(_path)) {
    yield RxResult.error(Exception("请求路径不能为空 path:$_path"));
    return;
  }

  if (!(await _checkNetWork())) {
    yield RxResult.error(NetworkException("Network not available"));
    return;
  }

  _cacheMode ??= (_rxNet.getBaseCacheMode() ?? CacheMode.ONLY_REQUEST);

  bool keepLooping;
  do {
    keepLooping = _isLoop;
    switch (_cacheMode!) {
      case CacheMode.ONLY_REQUEST:
        yield* _networkRequestStream(shouldCache: false);
        break;
      case CacheMode.FIRST_USE_CACHE_THEN_REQUEST:
        try {
          final cacheResult = await _readCache<T>();
          yield cacheResult;
        } catch (e) {
          // Cache errors are ignored, proceed to network.
        }
        yield* _networkRequestStream(shouldCache: true);
        break;
      case CacheMode.REQUEST_FAILED_READ_CACHE:
        bool networkSucceeded = false;
        await for (final netResult
            in _networkRequestStream(shouldCache: true)) {
          if (netResult.isSuccess) {
            networkSucceeded = true;
          }
          yield netResult;
        }
        if (!networkSucceeded) {
          try {
            final cacheResult = await _readCache<T>();
            yield cacheResult;
          } catch (e) {
            // If cache also fails, the last network error is already emitted.
          }
        }
        break;
      case CacheMode.CACHE_EMPTY_OR_EXPIRED_THEN_REQUEST:
        bool yieldedFromCache = false;
        if (!_requestIgnoreCacheTime) {
          try {
            final cacheResult = await _readCache<T>();
            yield cacheResult;
            yieldedFromCache = true;
          } catch (e) {
            // Cache failed, proceed to network.
          }
        }
        if (!yieldedFromCache) {
          yield* _networkRequestStream(shouldCache: true);
        }
        break;
      case CacheMode.ONLY_CACHE:
        try {
          final cacheResult = await _readCache<T>();
          yield cacheResult;
        } catch (e) {
          yield RxResult.error(e);
        }
        break;
    }

    if (keepLooping) {
      await Future.delayed(_loopInterval);
    }
  } while (keepLooping);
}