2016-02-16 21 views
19

Giả sử tôi có ứng dụng nhắn tin tức thì phát âm thanh tiếng bíp mỗi khi có tin nhắn đến. Tôi muốn debounce tiếng bíp, nhưng tôi muốn phát âm thanh tiếng bíp cho tin nhắn đầu tiên đến và không phải cho những âm thanh sau (trong khoảng thời gian là 2 giây).RxSwift - Debounce/Throttle "nghịch đảo"

Ví dụ khác có thể là: ứng dụng của tôi gửi thông báo nhập (vì vậy người dùng tôi đang trò chuyện có thể thấy rằng tôi đang nhập tin nhắn). Tôi muốn gửi thông báo nhập khi tôi bắt đầu nhập nhưng chỉ gửi thông báo mới trong khoảng thời gian X giây, vì vậy tôi không gửi thông báo nhập cho mỗi ký tự tôi nhập.

Điều này có hợp lý không? Có một nhà điều hành cho điều đó? Nó có thể đạt được với các nhà khai thác hiện tại?

Đây là mã của tôi cho ví dụ đầu tiên. Tôi đang giải quyết nó ngay bây giờ với debounce, nhưng nó không phải là lý tưởng. Nếu tôi nhận được 1000 tin nhắn trong khoảng thời gian 1 giây, nó sẽ không phát âm thanh cho đến khi tin nhắn cuối cùng đến (tôi muốn phát âm thanh trên tin nhắn đầu tiên).

self.messagesHandler.messages 
      .asObservable() 
      .skip(1) 
      .debounce(2, scheduler: MainScheduler.instance) 
      .subscribeNext { [weak self] message in 
        self?.playMessageArrivedSound() 
      }.addDisposableTo(self.disposeBag) 

Cảm ơn!

+0

Đây là một lời giải thích tốt https://medium.com/@dkhuong291/throttle-vs-debounce-in-rxswift-86f8b303d5d4 – onmyway133

Trả lời

20

Cập nhật cho RxSwift 3 và cải thiện throttle hành

Với hành vi mới của throtlle điều hành, được giới thiệu trong RxSwift 3.0.0-beta.1, bạn có thể sử dụng nó giống như thế:

downloadButton.rx.tap 
    .throttle(3, latest: false, scheduler: MainScheduler.instance) 
    .subscribe(onNext: { _ in 
     NSLog("tap") 
    }).addDisposableTo(bag) 

Phiên bản cũ của câu trả lời

Sử dụng toán tử window và sau đó chuyển đổi Observable<Observable<Type>> thành phẳng Observable sử dụng flatMap.

Mã mẫu này chỉ in 'nhấn' cho lần nhấn đầu tiên trong mỗi 3 giây cửa sổ (hoặc nếu số nhấn vượt quá 10000).

downloadButton.rx_tap 
    .window(timeSpan: 3, count: 10000, scheduler: MainScheduler.instance) 
    .flatMap({ observable -> Observable<Void> in 
     return observable.take(1) 
    }) 
    .subscribeNext { _ in 
     NSLog("tap") 
    }.addDisposableTo(bag) 
+0

Tôi hiện đang sử dụng một giải pháp tương tự, nhưng tôi cảm thấy có chỗ để cải thiện. Tôi muốn tránh đăng ký gấp đôi. Cảm ơn bạn đã trả lời! –

+3

Chắc chắn có chỗ để cải thiện. Bây giờ nó hoạt động mà không cần đăng ký gấp đôi. –

1

Cửa sổ là giải pháp tuyệt vời, nhưng tôi thấy nhà điều hành mẫu trực quan hơn và cũng có hành vi đúng.

messagesHandler.messages 
       .sample(Observable<Int>.timer(0.0, period: 2.0, scheduler: MainScheduler.instance)) 
       .subscribeNext { [weak self] message in 
        self?.playMessageArrivedSound() 
       }.addDisposableTo(self.disposeBag) 

Hoạt động của bướm ga không làm những gì tôi nghĩ.

Đối với những người đó cũng tìm ga là quá khó hiểu:

"ga sẽ chỉ về phía trước một sự kiện khi nguồn quan sát đã ngừng gửi các sự kiện cho thời gian nhất định này không hoạt động tốt với các giao sự kiện thường xuyên" for more details.

Trong trường hợp này, bộ lọc mà bạn muốn là

sample(Observable<Int>.timer(0.0, period: 2.0, scheduler: MainScheduler.instance)) 
Các vấn đề liên quan