Как принять первое вхождение, а затем подавить события на 2 секунды (RxJS) - PullRequest
8 голосов
/ 04 марта 2011

Я думаю, что RxJS должен идеально подходить для подавления повторных нажатий кнопок в течение 2 секунд. Однако я борюсь с реализацией.

var $button = $('#myButton').button();
$button
    .toObservable("click")
    //.Throttle(2000) // Wouldn't fire the first event instantly :-(
    .Subscribe(function(){ alert('clicked'); }); 

Я уже создал jsFiddle для вашего удобства. Вам нужно прокрутить эту скрипку вниз, потому что я просто вставил Rx внутрь, так как не смог найти CDN.

http://jsfiddle.net/cburgdorf/mUMFA/2/

Ответы [ 5 ]

5 голосов
/ 07 марта 2011

Я преобразовал ответ Сергея в JavaScript и думаю, что это должен быть последний путь.

var $button = $('#myButton').button();
    $button
        .toObservable("click")
        .Take(1)
        .Merge(Rx.Observable.Empty().Delay(2000))
        .Repeat()
        .Subscribe(function(){ console.log('clicked'); }

Насколько я понимаю, это решение действительно лучше, потому что оно не зависит от побочного эффекта, который делает его дажелучше с точки зрения компоновки.

Как отметил Сергей, вы могли бы даже пойти дальше и реализовать свой собственный комбинатор, например, так:

Rx.Observable.prototype.OneInTime = function(delay){
 return this
        .Take(1)
        .Merge(Rx.Observable.Empty().Delay(delay))
        .Repeat();
};

Таким образом, наш приведенный выше пример можно сократить до:

var $button = $('#myButton').button();
    $button
        .toObservable("click")
        .OneInTime(2000)
        .Subscribe(function(){ console.log('clicked'); });
3 голосов
/ 06 марта 2011

Вот как я бы это сделал в RxNet (извините, я не знаком с RxJS, поэтому не уверен, что это возможно):

    public static IObservable<T> SupressDoubleClicks<T>(
        this IObservable<T> source, TimeSpan delay)
    {
        return source
            .Take(1)
            .Merge(Observable.Empty<T>().Delay(delay))
            .Repeat();
    }
2 голосов
/ 04 марта 2011

На самом деле, Мэтью из команды Rx был так любезен, чтобы отправить мне ответ через твиттер: http://twitter.com/#!/mattpodwysocki/status/43731812513624064

Итак, что вы можете сделать, это:

var $button = $('#myButton').button();
$button
    .toObservable("click")
    .Do(function(){ 
        alert('clicked'); 
        $button.button('disable'); 
    })
    .Delay(2000)
    .Do(function(){ $button.button('enable'); })
    .Subscribe();   

http://jsfiddle.net/cburgdorf/mUMFA/5/

Однако: по соображениям физической нагрузки. Я бы предпочел, чтобы он работал без настройки включения / выключения, а просто подавлял события на 2 секунды после первого вхождения

В мраморной речи я ищу это:

O Поток: X --- X --- X --- X --- X --- X --- X

RxStream: X ------------ X ------------ X

0 голосов
/ 12 декабря 2014

Я многому научился из этой темы, и на самом деле итерация сумасшедший вкус * является самой чистой.Но я хотел вернуть поток событий, который можно составить - как в преобразованном ответе Сергея .Итак, вот мой метод ...

Rx.Observable.prototype.throttleOnFirst = function(ms){

    var subject = new Rx.Subject();

    var throttler = this
        .do(function(data){subject.onNext(data)})
        .take(1)
        .delay(ms)
        .repeat()
        .subscribe()

    return subject;
};

Мой в угловом, поэтому я использую его так ...

var goToChaseTrigger = $scope.$createObservableFunction('goToChase');
var throttleAfterFirst = goToChaseTrigger
    .throttleOnFirst(2000)
    .subscribe(function(d){console.log('throttleOnFirst>',d)})
0 голосов
/ 06 марта 2011

Безумно вкусно!

Понял:

var $button = $('#myButton').button();
$button
    .toObservable("click")
    .Do(function(){ console.log('clicked'); })
    .Take(1)
    .Delay(2000)
    .Repeat()
    .Subscribe()
...