2017-05-23 4 views
2

짧은 버전 : Akavache를 추가하지 않은 상태에서처럼 내 코드 (https://github.com/akavache/Akavache/blob/501b397d8c071366c3b6783aae3e98695b3d7442/src/Akavache/Portable/JsonSerializationMixin.cs#L202)에 Akavache와 같은 GetAndFetchLatest 메소드를 어떻게 구현합니까?가능한 한 빨리 요청과 출력 결과를 결합하십시오.

긴 버전 : 디스크에서 T의 목록을 반환하는 메서드가 있고 HTTP 서비스에서 동일한 형식 List<T>을 반환하는 메서드가 있습니다. 둘 다 비동기로 래핑 됨 Task<List<T>>

내보기 모델에서는 Observable<List<T>>을 반환하는 1 메서드 만 호출하려고합니다.

따라서 내 ViewModel에서 .Subscribe() 메서드를 사용하여 UI를 업데이트합니다. 본질적으로 데이터를 사용할 수 있다는 사실을 두 번 통보해야하며 구독의 코드도 두 번 수행됩니다.

이 기능은 GetAndFetchLatest 방법의 형태로 Akavache에서 사용할 수 있습니다. 그러나 RX에서 유창하게 구사할 수는 없으므로이 2 데이터 메서드 호출을 사용하여 구현할 수 있습니다.

참고 : 두 가지 작업을 모두 기다리지 않으려 고합니다. 동시에 데이터를 반환하고 데이터를 반환하면 동시에 트리거하려고합니다. Observable.

팁이 있습니까? GetFromWeb 완료 GetFromDisk 전에 어떤 경우에는 당신이 무시하려는 있으리라 믿고있어 그 가능성이 있지만 가능한 시나리오를 처리하지 않는, 그러나

var merged = Observable.Merge(
    GetFromWeb().ToObservable(), 
    GetFromDisk().ToObservable() 
); 

//Same thing using extension syntax 
var simply = GetFromWeb().ToObservable() 
    .Merge(GetFromDisk().ToObservable()); 

:

답변

3

을 감안할 때 Task<List<T>> GetFromWeb()Task<List<T>> GetFromDisk()는 간단한 대답은 이것이다 GetFromDisk의 결과. 그것을 처리하기 위해, 당신은 몇 가지 체조를 요구하는거야 :

public IObservable<T> Prioritize<T>(params IObservable<T>[] orderedByDescendingPriority) 
{ 
    return orderedByDescendingPriority 
     .Select((o, i) => o.Select(item => Tuple.Create(orderedByDescendingPriority.Length - i, item))) 
     .Merge() 
     .Select(t => new Func<Tuple<int, T, bool>, Tuple<int, T, bool>>(t2 => Tuple.Create(Math.Max(t2.Item1, t.Item1), t.Item2, t.Item1 >= t2.Item1))) 
     .Scan(Tuple.Create(0, default(T), false), (t, f) => f(t)) 
     .Where(t => t.Item3) 
     .Select(t => t.Item2); 
} 

var merged = Prioritize(
    GetFromWeb().ToObservable(), 
    GetFromDisk().ToObservable() 
); 

편집 :

당신은 항상 GetFromWeb 다음은 간단한 Concat 작동되기 전에 GetFromDisk 항상 표시하십시오. .NET 작업이 함수를 참조하자마자 자동으로 시작되기 때문에이 방법이 효과적입니다.

var t1 = GetFromDisk(); 
    var t2 = GetFromWeb(); 

    var merged = Observable.Concat(
     t1.ToObservable(), 
     t2.ToObservable() 
    ); 
+0

이것은 유망 해 보입니다! 내가 이것을 시험해 보자. – Depechie

+0

fromDisk 결과가 푸시 된 후 fromWeb 결과의 우선 순위를 지정하지 않고 연기하는 방법이 있습니까? fromWeb이 시작될 때까지 기다리지 않고 fromDisk 중 하나가 푸시 된 후 결과를 observable에 추가하는 것을 기다리시겠습니까? – Depechie

+0

그래서 동시에 요청을 시작하고, 'FromDisk'가 얼마나 오래 걸리는지 상관없이 항상 먼저 FromWeb이 나오고, 가능한 한 빨리 FromWeb이옵니다. – Shlomo