RX 最佳实践:选择有副作用或使用订阅

本文关键字:副作用 最佳 选择 RX | 更新日期: 2023-09-27 18:36:13

我将事件(来自按钮的分页事件)转换为IObservable,并从服务异步接收结果。

作为副作用,我必须更新子视图。我有两个解决方案:

  1. 选择中的副作用:

        //Converting events to a "stream" of search results.
        IObservable<SearchResult> resultsFromPageChange = Observable.FromEventPattern<EventArgs>(this,
            "PageChangedEvent")
            .Throttle(TimeSpan.FromMilliseconds(500))
            .Select(async ev =>
             {
                 var input = new SearchResultInput()
                 {
                     PageSize = PageSize,
                     PageIndex = PageIndex,
                     SearchOptions = _currentSearchOptions,
                     SearchText = SearchText.Value
                 };
                 var result = await GetPagedComponents(input);
                 //Side effect
                 ActivateAttributesView(result.Components.FirstOrDefault());
                 return result;
             }).Switch(); //flatten and take most recent.
    
  2. 在订阅中做副作用:

        //Converting events to a "stream" of search results.
        IObservable<SearchResult> resultsFromPageChange = Observable.FromEventPattern<EventArgs>(this,
            "PageChangedEvent")
            .Throttle(TimeSpan.FromMilliseconds(500))
            .Select(async ev =>
            {
                var input = new SearchResultInput()
                {
                    PageSize = PageSize,
                    PageIndex = PageIndex,
                    SearchOptions = _currentSearchOptions,
                    SearchText = SearchText.Value
                };
                return await GetPagedComponents(input);
            }).Switch(); //flatten and take most recent.
        //Do side effect in the subscribe
        resultsFromPageChange.Subscribe(x =>
        {
            if (x != null)
                ActivateAttributesView(x.Components.FirstOrDefault());
        });
    

这两种方法都有效。我应该选择哪种解决方案,为什么?

感谢。

因为存在为什么这会产生值的问题,所以下面是完整的代码:

        //Converting events to a "stream" of search results.
        IObservable<SearchResult> resultsFromPageChange = Observable.FromEventPattern<EventArgs>(this,
            "PageChangedEvent")
            .Throttle(TimeSpan.FromMilliseconds(500))
            .Select(async ev =>
            {
                var input = new SearchResultInput()
                {
                    PageSize = PageSize,
                    PageIndex = PageIndex,
                    SearchOptions = _currentSearchOptions,
                    SearchString = SearchString.Value
                };
                return await SearchComponentsPaged(input);
            }).Switch(); //flatten and take most recent.
        SearchString = new ReactiveProperty<string>(""); //Bound to TextBox.Text 
        //Create a "stream" of search results from a string given by user (SearchString)
        SearchResult = SearchString
            .SetValidateNotifyError(s => _componentDataService.ValidateSearchStringLength(s).Errors)
            .Throttle(TimeSpan.FromMilliseconds(500))
            .Select(async term =>
            {
                var input = new SearchResultInput()
                    {
                        PageSize = PageSize,
                        PageIndex = PageIndex,
                        SearchOptions = _currentSearchOptions,
                        SearchString = term
                    };
                return await SearchComponentsPaged(input);
            })
            .Switch()
            .Merge(resultsFromPageChange) //Merge the result of paging and text changing.  
            .ToReactiveProperty();
        //Update Attributes view
        SearchResult.Subscribe(searchResult =>
        {
            if (searchResult != null)
            {
                ActivateAttributesView(searchResult.Components.FirstOrDefault());
                SearchResult.Value.TotalItemsCount = searchResult.TotalItemsCount;
            }
        });

它的实际作用是在搜索字符串更改时向数据库发送搜索请求并获得分页结果,或者在收到 PageChangedEvent 时获取具有相同搜索字符串的另一个页面。是否 .合并(...)订阅?

RX 最佳实践:选择有副作用或使用订阅

我会选择你的第二个解决方案。它更灵活,因为不同的订阅者可以选择有不同的副作用。它还分离了关注点,Rx 查询生成数据,订阅者随心所欲地使用数据。

选择和纯函数(无副作用)是最佳做法。它更清楚地显示了意图。

此外,由于可观察量是可组合的,并且您可能希望在其他地方再次使用数据流,因此最好尽可能明确地使用副作用。