如何将重新加载和IsLoding状态添加到二级可见对象

How to add quot;reloadquot; and IsLoading status to 2nd level Observable(如何将重新加载和IsLoding状态添加到二级可见对象)
本文介绍了如何将重新加载和IsLoding状态添加到二级可见对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我觉得我在试着重新发明轮子,所以我最好问问。

已给定

  • 我有一个Observable<T> source
  • Task LoadAsync<T>(T value)方法

时间

  • 我使用选择/切换模式在源发出时调用LoadMethod

    observable
       .Select(value => Observable.FromAsync(cancellationToken => LoadAsync(value, cancellationToken)))
       .Switch()
       .Subscribe(); 
    

然后

  1. 如何添加重新加载功能?
  2. 如何报告IsLoding状态:LoadAsync是否正在运行
  3. source完成时如何取消LoadAsync

我想创建一些可重用的方法或类,以实现对#1和#2的回答。

我到目前为止:https://dotnetfiddle.net/0zPhBE

public class ReactiveLoader<T> : IDisposable
{
    private readonly BehaviorSubject<bool> _isLoading = new(false);
    private readonly Subject<Unit> _completes = new();
    private readonly Subject<T> _reloads = new Subject<T>();
    private readonly IDisposable _subscription;

    public bool IsLoading => _isLoading.Value;
    public IObservable<bool> IsLoadingObservable => _isLoading.Skip(1).DistinctUntilChanged(); //Not nice

    public ReactiveLoader(IObservable<T> observable, Func<T, CancellationToken, Task> handler)
    {           
        _subscription = observable
            .Finally(() => //Not nice
            {
                 _completes.OnNext(Unit.Default);
            })
            .Merge(_reloads)
            .Do(_ => _isLoading.OnNext(true))
            .Select(value => Observable.FromAsync(cancellationToken => handler(value, cancellationToken)))
            .Switch()
            .Do(_ => _isLoading.OnNext(false))
            .TakeUntil(_completes) //cancels loading when observable completes
            .Subscribe();
    }

    public void Reload()
    {
         _reloads.OnNext(??); //needs last value of source
    }

    public void Dispose()
    {
        _completes.OnNext(Unit.Default);
        _subscription.Dispose();
    }
}

推荐答案

以下是一种方法:

IObservable<bool> sequence = source.Publish(published => published
    .CombineLatest(_reloads, (x, _) => x)
    .Select(x => Observable.FromAsync(ct => LoadAsync(x, ct)).Select(_ => false).Prepend(true))
    .Switch()
    .Do(_isLoading)
    .TakeUntil(published.LastOrDefaultAsync()));

CombineLatest运算符将在_reloads每次发出信号时重新发出最新的值。

.Select(_ => false).Prepend(true)将内部可观测对象从IObservable<Unit>转换为IObservable<bool>,从而发出加载状态信号。

TakeUntil(published.LastOrDefaultAsync())将在source终止时立即终止序列(不等待任何挂起的LoadAsync操作)。

这篇关于如何将重新加载和IsLoding状态添加到二级可见对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

DispatcherQueue null when trying to update Ui property in ViewModel(尝试更新ViewModel中的Ui属性时DispatcherQueue为空)
Drawing over all windows on multiple monitors(在多个监视器上绘制所有窗口)
Programmatically show the desktop(以编程方式显示桌面)
c# Generic Setlt;Tgt; implementation to access objects by type(按类型访问对象的C#泛型集实现)
InvalidOperationException When using Context Injection in ASP.Net Core(在ASP.NET核心中使用上下文注入时发生InvalidOperationException)
LINQ many-to-many relationship, how to write a correct WHERE clause?(LINQ多对多关系,如何写一个正确的WHERE子句?)