Using Rx Framework for async calls using the void AsyncMethod(Action callback) pattern

前端 未结 3 1145
深忆病人
深忆病人 2020-12-20 00:26

I\'ve seen tons of examples on how to use the Observable.FromAsyncPattern() in the Rx Framework to simplify Async calls, but I\'m using an interface that doesn\'t use the st

相关标签:
3条回答
  • 2020-12-20 00:50

    Try Observable.Create(), perhaps something like this:

    public IObservable<Object> ObserveAllObjects()
    {
        return Observable.Create<Object>(
            observer =>
                () => GetAllObjects(objects => objects.ForEach(o => observer.OnNext(o))));
    }
    
    0 讨论(0)
  • 2020-12-20 01:04

    I like Observable.Create for this, but @dahlbyk answer is incorrect(misses completion and performs the action in the unsubscribe handler). Should be something like this:

        IObservable<List<T>> FromListCallbackPattern<T>(
            Action<Action<List<T>>> listGetter)
        {
            return Observable
                .Create<List<T>>(observer =>
                {
                    var subscribed = true;
                    listGetter(list =>
                    {
                        if (!subscribed) return;
                        observer.OnNext(list);
                        observer.OnCompleted();
                    });
                    return () =>
                    {
                        subscribed = false;
                    };
                });
        }
    

    Also, since the originating API returns an entire list altogether, I don't see a reason to transform it to observable too early. Let the resulting observable return a list as well, and if a caller needs to flatten it, he can use .SelectMany

    0 讨论(0)
  • 2020-12-20 01:08
    Func<IObservable<TRet>> FromListCallbackPattern(Action<Action<List<TRet>>> function)
    {
        return () => {
            // We use a ReplaySubject so that if people subscribe *after* the
            // real method finishes, they'll still get all the items
            ret = new ReplaySubject<TRet>();
    
            function((list) => {
                // We're going to "rebroadcast" the list onto the Subject
                // This isn't the most Rx'iest way to do this, but it is the most
                // comprehensible :)
                foreach(var v in list) {
                    ret.OnNext(v);
                }
                ret.OnCompleted();
            });
    
            return ret;
        };
    }
    

    Now, you can do something like:

    var getAllUsers = FromListCallbackPattern(mClient.GetAllUsers);
    getAllUsers().Subscribe(x => /* ... */);
    
    0 讨论(0)
提交回复
热议问题