اپراتور Debounce
این اپراتور دیتای observable را با تاخیری که خودمون مشخص میکنیم منتشر میکنه.
کاربرد:
وقتی کاربر سرچ میکنه، خوب نیست که به ازای هر کاراکتری که مینویسه یه درخواستی به سرور بره. بهتره مثلا بعد از دو ثانیه برای عبارتی که نوشته، یک درخواست سرچ به سرور بره. اینجوری درخواست های بیهوده به سرور نمیره و کدنویسی بهینه تر هست.
در کد زیر از کتابخونه RxBinding استفاده شده ( یعنی محتویات یک ادیت تکست observable شده). هر چی توی ادیت تکست نوشته بشه با تاخیر یک ثانیه منتشر خواهد شد.
edtText = findViewById(R.id.edtText);
RxTextView.textChanges(edtText)
.debounce(1000, TimeUnit.MILLISECONDS)
.subscribe(new Observer<CharSequence>() {
@Override
public void onSubscribe(@NonNull Disposable d) {
}
@Override
public void onNext(@NonNull CharSequence charSequence) {
Log.d(TAG, charSequence.toString());
}
@Override
public void onError(@NonNull Throwable e) {
}
@Override
public void onComplete() {
}
});
نکته:
کد RxTextView.textChanges قبل از اینکه تغییری رو منتشر (emit) کنه، مقدار فعلی رو به observer میفرسته. یعنی وقتی اپلیکیشن برای اولین بار اجرا میشه یا rotate میشه، متد onNext در observer فراخونی میشه.
برای حل این مشکل observable رو به صورت زیر مینویسیم: (skip حتما باید بعد از debounce باشه)
RxTextView.textChanges(edtText)
.debounce(1000, TimeUnit.MILLISECONDS)
.skip(1)
نکته مهم تر:
بعضی جاها گفتن برای اینکه اولین بار مقداری منتشر نشه از SkipInitialValue قبل از debounce استفاده کنیم. این روش فقط برای اولین اجرای اپ جواب میده و با rotate شدن گوشی دوباره مقدار اولیه منتشر میشه. SkipInitialValue رو نمیشه بعد از debounce فراخونی کرد. بنابراین راه درست استفاده از skip بعد از debounce هست.