Rx Show Loading(进度条或类似的东西)如果 Web 请求花费的时间太长
Rx Show Loading(Progress Bar or something like that) If Web request takes too long
我正在开发 Xamarin.Ios 小词典应用程序,它向服务器发送一个 GET 请求,它 returns 通过键(词)输入值,文本输入在 SearchBar 上,我在它的 TextChanged 上可以观察到事件,好事是我设法通过 observables 发送请求,但如果请求花费超过 1 或 2 秒,我想显示 LoadingView ......我尝试了 Buffer() 但它没有工作,所以这是代码谢谢!!
var dataStream = Observable.FromEventPattern<UISearchBarTextChangedEventArgs>(ev => searchBar.TextChanged += ev,
ev => searchBar.TextChanged -= ev)
.Select(o => o.EventArgs.SearchText)
.DistinctUntilChanged()
.Throttle(TimeSpan.FromMilliseconds(300))
.ObserveOn(SynchronizationContext.Current)
.Select(t =>
{
#if DEBUG
Console.WriteLine(t);
#endif
var instance = TranslateWebClient.Instance;//this is WebClient From where Get Request is made
var data = instance.GetWordAsync(t);
return data.ToObservable().ObserveOn(SynchronizationContext.Current);
})
.Switch();
dataStream.Subscribe(o =>
{
if (o == null || o.Count() == 0)
{
wordsTableView.DataSource = null;
wordsTableView.ReloadData();
return;
}
_words = o;
initDataToUI();
}, ex =>
{
if (ex is WebClient.NoInternetException)
{
//handle exception
}
});
所以我认为这样的事情会奏效。添加此枚举,或使用类似的东西(如果可用):
enum LoadState
{
InitialState,
RequestSent,
ResponseLate,
ResponseReceived
}
...然后将您的 dataStream
声明更改为以下内容:
var requestStream = Observable.FromEventPattern<UISearchBarTextChangedEventArgs>(ev => searchBar.TextChanged += ev,
ev => searchBar.TextChanged -= ev)
.Select(o => o.EventArgs.SearchText)
.DistinctUntilChanged()
.Throttle(TimeSpan.FromMilliseconds(300))
.ObserveOn(SynchronizationContext.Current)
.Select(t =>
{
#if DEBUG
Console.WriteLine(t);
#endif
var instance = TranslateWebClient.Instance;//this is WebClient From where Get Request is made
var data = instance.GetWordAsync(t);
return data.ToObservable().ObserveOn(SynchronizationContext.Current);
})
.Publish()
.RefCount();
requestStream
.SelectMany(o => Observable.Merge(
Observable.Return(LoadState.RequestSent),
Observable.Timer(TimeSpan.FromSeconds(1)).Select(_ => LoadState.ResponseLate),
o.Select(_ => LoadState.ResponseReceived))
)
.Scan(LoadState.InitialState,
(previousState, newState) => previousState == LoadState.ResponseReceived && newState == LoadState.ResponseLate
? LoadState.ResponseReceived
: newState
)
.Subscribe(state =>
{
if(state == LoadState.ResponseLate)
; //enable loading UI
else
; //disable loading UI
});
var dataStream = requestStream.Switch();
说明:requestStream
发出代表每个 Web 请求的可观察对象。我认为新的订阅符合你心目中的业务规则:当延迟达到 1 秒或更长时间时显示等待 UI,然后如果他们提出新请求或收到回复。
我正在开发 Xamarin.Ios 小词典应用程序,它向服务器发送一个 GET 请求,它 returns 通过键(词)输入值,文本输入在 SearchBar 上,我在它的 TextChanged 上可以观察到事件,好事是我设法通过 observables 发送请求,但如果请求花费超过 1 或 2 秒,我想显示 LoadingView ......我尝试了 Buffer() 但它没有工作,所以这是代码谢谢!!
var dataStream = Observable.FromEventPattern<UISearchBarTextChangedEventArgs>(ev => searchBar.TextChanged += ev,
ev => searchBar.TextChanged -= ev)
.Select(o => o.EventArgs.SearchText)
.DistinctUntilChanged()
.Throttle(TimeSpan.FromMilliseconds(300))
.ObserveOn(SynchronizationContext.Current)
.Select(t =>
{
#if DEBUG
Console.WriteLine(t);
#endif
var instance = TranslateWebClient.Instance;//this is WebClient From where Get Request is made
var data = instance.GetWordAsync(t);
return data.ToObservable().ObserveOn(SynchronizationContext.Current);
})
.Switch();
dataStream.Subscribe(o =>
{
if (o == null || o.Count() == 0)
{
wordsTableView.DataSource = null;
wordsTableView.ReloadData();
return;
}
_words = o;
initDataToUI();
}, ex =>
{
if (ex is WebClient.NoInternetException)
{
//handle exception
}
});
所以我认为这样的事情会奏效。添加此枚举,或使用类似的东西(如果可用):
enum LoadState
{
InitialState,
RequestSent,
ResponseLate,
ResponseReceived
}
...然后将您的 dataStream
声明更改为以下内容:
var requestStream = Observable.FromEventPattern<UISearchBarTextChangedEventArgs>(ev => searchBar.TextChanged += ev,
ev => searchBar.TextChanged -= ev)
.Select(o => o.EventArgs.SearchText)
.DistinctUntilChanged()
.Throttle(TimeSpan.FromMilliseconds(300))
.ObserveOn(SynchronizationContext.Current)
.Select(t =>
{
#if DEBUG
Console.WriteLine(t);
#endif
var instance = TranslateWebClient.Instance;//this is WebClient From where Get Request is made
var data = instance.GetWordAsync(t);
return data.ToObservable().ObserveOn(SynchronizationContext.Current);
})
.Publish()
.RefCount();
requestStream
.SelectMany(o => Observable.Merge(
Observable.Return(LoadState.RequestSent),
Observable.Timer(TimeSpan.FromSeconds(1)).Select(_ => LoadState.ResponseLate),
o.Select(_ => LoadState.ResponseReceived))
)
.Scan(LoadState.InitialState,
(previousState, newState) => previousState == LoadState.ResponseReceived && newState == LoadState.ResponseLate
? LoadState.ResponseReceived
: newState
)
.Subscribe(state =>
{
if(state == LoadState.ResponseLate)
; //enable loading UI
else
; //disable loading UI
});
var dataStream = requestStream.Switch();
说明:requestStream
发出代表每个 Web 请求的可观察对象。我认为新的订阅符合你心目中的业务规则:当延迟达到 1 秒或更长时间时显示等待 UI,然后如果他们提出新请求或收到回复。