节气门,但如果来不及,则放弃结果 [英] Throttle but discard results if they come too late

查看:96
本文介绍了节气门,但如果来不及,则放弃结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个UI,用户可以在其中输入搜索字词,并且列表会不断更新,并提供建议.

I'm writing a UI where the user can type in a search term and a list get continuously updated offering suggestions.

尽管我的第一个想法是Rx原语Throttle是完美的匹配,但是却让我半途而废.

My first though was that the Rx primitive Throttle was a perfect match but it gets me half there.

获取这些建议需要一些时间,因此我可以在非UI线程上异步获取它们.

The suggestions take a while to fetch so I get them asynchronously on not on the UI thread.

问题是,如果用户再次输入油门时间跨度,我想丢弃/跳过/丢弃结果.

The problem is that I want to discard/skip/throw away a result if the user types af the throttle time span again.

例如:

  • 时间开始并且用户按下一个键:0ms
  • 油门设置为100ms.
  • 提取过程需要200毫秒.
  • 在150毫秒内,用户按下了另一个键

现在,通过Throttle,第一次提取仍将继续执行gui建议列表. 我想学习的是如何取消第一次取回,因为它不再相关了? 只有第二次按键才能触发对gui的更新.

Now with Throttle the first fetch will still go ahead an populate the gui suggestion list. What I like to learn is how can I cancel that first fetch as it is not relevant anymore? Only the second keypress should trigger an update to the gui.

这是我尝试过的

(我使用ReactiveUI,但Q大约是Rx)

(I use ReactiveUI but the Q is about Rx)

public IEnumerable<usp_getOpdrachtgevers_Result> Results { get; set; } // [Reactive] pu

public SearchOpdrachtgeverVM()
{

    this.WhenAnyValue(x => x.FirstName,
                      x => x.LastName
        )
        .Throttle(TimeSpan.FromMilliseconds(200))
        .Subscribe(async vm => Results = await PopulateGrid());
}

private async Task<IEnumerable<usp_getOpdrachtgevers_Result>> PopulateGrid()
{

    return await Task.Run(
             () => _opdrachtgeversCache
                         .Where(x =>
                                x.vNaam.Contains(FirstName)
                                && x.vLastName.Contains(LastName)
                         )

             );

}

推荐答案

如果将异步任务变成可观察对象,则这似乎是Switch的经典用法:

If you turn your async Task into an Observable, this looks like a classic use for Switch:

this.WhenAnyValue(x => x.FirstName,
                  x => x.LastName
    )
    .Throttle(TimeSpan.FromMilliseconds(100)) 
    .Select(l => PopulateGrid().ToObservable())
    .Switch()
    .Subscribe(vm => Results = vm);

Throttle应该用于在用户键入时禁止呼叫.因此,您可以根据需要调整该TimeSpan.

Throttle should be used to suppress calls while the user is typing. So adjust that TimeSpan as you like.

这篇关于节气门,但如果来不及,则放弃结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆