J'essaie de créer un opérateur Rx qui semble assez utile, mais je n'ai étonnamment pas trouvé de questions sur Stackoverflow qui correspondent précisément. J'aimerais créer une variante de Throttle
qui laisse passer les valeurs immédiatement s'il y a eu une période d'inactivité. Le cas d'utilisation que j'imagine est quelque chose comme ceci :
J'ai une liste déroulante qui déclenche une requête web lorsque la valeur est modifiée. Si l'utilisateur maintient la touche fléchée enfoncée et fait défiler rapidement les valeurs, je ne veux pas déclencher une requête pour chaque valeur. Mais si j'étrangle le flux, l'utilisateur doit attendre la durée de l'étranglement chaque fois qu'il sélectionne une valeur dans la liste déroulante de manière normale.
Ainsi, alors qu'un Throttle
ressemble à ça :
Je veux créer ThrottleSubsequent
qui ressemblent à ça :
Notez que les billes 1, 2 et 6 sont passées sans délai car elles suivent chacune une période d'inactivité.
Ma tentative ressemble à ce qui suit :
public static IObservable<TSource> ThrottleSubsequent<TSource>(this IObservable<TSource> source, TimeSpan dueTime, IScheduler scheduler)
{
// Create a timer that resets with each new source value
var cooldownTimer = source
.Select(x => Observable.Interval(dueTime, scheduler)) // Each source value becomes a new timer
.Switch(); // Switch to the most recent timer
var cooldownWindow = source.Window(() => cooldownTimer);
// Pass along the first value of each cooldown window immediately
var firstAfterCooldown = cooldownWindow.SelectMany(o => o.Take(1));
// Throttle the rest of the values
var throttledRest = cooldownWindow
.SelectMany(o => o.Skip(1))
.Throttle(dueTime, scheduler);
return Observable.Merge(firstAfterCooldown, throttledRest);
}
Este semble mais j'ai du mal à raisonner et j'ai l'impression qu'il y a des cas limites où les choses peuvent se gâter avec des valeurs en double ou autre. J'aimerais avoir l'avis d'utilisateurs de Rx plus expérimentés pour savoir si ce code est correct ou non, et/ou s'il existe une façon plus idiomatique de le faire.