根据条件对rx进行去抖动-RxSwift

时间:2019-01-06 13:23:39

标签: swift rx-swift

我在Kotlin中使用它根据条件进行反跳:

// variables
private val subject_isUpdating = PublishSubject.create<Int>()
var lastClickedItem = -1


// inside onCreate
adapter_cartProducts.setOnItemClickedListener { position ->
     subject_isUpdating.onNext(position)
}


// subscribing 
        subject_isUpdating
            .debounce
            { position ->
                // here if lastClickedItem changed, no debounce
                if(position != lastClickedItem) {
                    lastClickedItem = position
                    Observable.empty()
                }
                // else if same item clicked -> debounce
                else Observable.timer(300, TimeUnit.MILLISECONDS) }
            .subscribe({ position ->
                updateOnWS(position, adapter_cartProducts.items[position])
            }, { error ->
                Timber.e(error) // printing the error
            })

这是RxJava中使用的去抖动选择器功能:

/**
 * Returns an Observable that mirrors the source ObservableSource, except that it drops items emitted by the
 * source ObservableSource that are followed by another item within a computed debounce duration.
 * <p>
 * <img width="640" height="425" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/debounce.f.png" alt="">
 * <dl>
 *  <dt><b>Scheduler:</b></dt>
 *  <dd>This version of {@code debounce} does not operate by default on a particular {@link Scheduler}.</dd>
 * </dl>
 *
 * @param <U>
 *            the debounce value type (ignored)
 * @param debounceSelector
 *            function to retrieve a sequence that indicates the throttle duration for each item
 * @return an Observable that omits items emitted by the source ObservableSource that are followed by another item
 *         within a computed debounce duration
 * @see <a href="http://reactivex.io/documentation/operators/debounce.html">ReactiveX operators documentation: Debounce</a>
 */
public final <U> Observable<T> debounce(Function<? super T, ? extends ObservableSource<U>> debounceSelector) {
    ObjectHelper.requireNonNull(debounceSelector, "debounceSelector is null");
    return RxJavaPlugins.onAssembly(new ObservableDebounce<T, U>(this, debounceSelector));
}

此代码的想法是,用户将单击列表项,并且当用户停止单击400ms或单击其他项时,该项将在Web服务上更新

可以在RxSwift中完成吗?

1 个答案:

答案 0 :(得分:1)

我不能说我特别喜欢您提供的代码,因为它依赖于外部变量。

以下是您要执行的操作员:

extension ObservableType where E: Equatable {

    func throttleUnlessChanged(_ dueTime: TimeInterval, scheduler: SchedulerType) -> Observable<E> {
        return Observable.create { observer in
            let lock = NSRecursiveLock()
            var last: E?
            var lastTime: RxTime?
            return self.subscribe { event in
                lock.lock(); defer { lock.unlock() }
                switch event {
                case .next(let element):
                    let now = scheduler.now
                    let timeIntervalSinceLast = lastTime != nil ? now.timeIntervalSince(lastTime!) : dueTime
                    if element != last {
                        observer.onNext(element)
                        last = element
                        lastTime = now
                    }
                    else if timeIntervalSinceLast >= dueTime {
                        observer.onNext(element)
                        last = element
                        lastTime = now
                    }
                case .error(let error):
                    observer.onError(error)
                case .completed:
                    observer.onCompleted()
                }
            }
        }
    }
}

以下是测试的要点:https://gist.github.com/dtartaglia/f5b041facfdcdd64630e0cb8cfc2cc5b