Hiểu về các toán tử Flow: Buffer, Conflate, Debounce và Sample

0 0 0

Người đăng: Kẻ hai mặt

Theo Viblo Asia

🧠 Vấn đề: Collector chậm

Khi làm việc với Flow trong Kotlin, đặc biệt là trong các tình huống producer phát dữ liệu nhanh và collector xử lý chậm, việc quản lý dòng dữ liệu trở nên quan trọng. Hãy xem xét ví dụ sau:

flow { for (i in 1..100) { emit(i) delay(100) // Emit every 100ms }
}.collect { value: Int -> delay(300) // Process for 300ms println("Processed $value")
}

Trong trường hợp này, collector chậm hơn producer, dẫn đến vấn đề backpressure. Mỗi toán tử dưới đây cung cấp một chiến lược khác nhau để xử lý tình huống này.

📦 Toán tử Buffer

Toán tử buffer tạo một channel với dung lượng xác định để lưu trữ các giá trị được phát trong khi collector đang xử lý các giá trị trước đó.

flow { for (i in 1..5) { emit(i) println("Emitting $i") delay(100) }
}.buffer(2) // Buffer capacity of 2 .collect { value: Int -> println("Collecting $value") delay(300) // Slow collector
} // Output:
// Emitting 1
// Emitting 2
// Emitting 3
// Collecting 1 (t=300ms)
// Collecting 2 (t=600ms)
// Emitting 4
// Emitting 5
// Collecting 3 (t=900ms)
// Collecting 4 (t=1200ms)
// Collecting 5 (t=1500ms) 

Kết quả

// Output:
// Emitting 1
// Emitting 2
// Emitting 3
// Collecting 1 (t=300ms)
// Collecting 2 (t=600ms)
// Emitting 4
// Emitting 5
// Collecting 3 (t=900ms)
// Collecting 4 (t=1200ms)
// Collecting 5 (t=1500ms)

Khi nào nên sử dụng buffer:

Khi bạn muốn lưu trữ một số lượng giá trị được phát cụ thể.

Khi bạn cần xử lý tất cả các giá trị nhưng muốn tách biệt tốc độ giữa producer và collector.

Khi thứ tự xử lý là quan trọng.

🔄 Toán tử Conflate

Toán tử conflate chỉ giữ lại giá trị mới nhất, bỏ qua các giá trị trung gian nếu collector không theo kịp.

flow { for (i in 1..5) { emit(i) println("Emitting $i") delay(100) }
}.conflate() .collect { value: Int -> println("Collecting $value") delay(300) // Slow collector
} // Output:
// Emitting 1
// Emitting 2
// Collecting 1 (t=300ms)
// Emitting 3
// Emitting 4
// Collecting 4 (t=600ms)
// Emitting 5
// Collecting 5 (t=900ms) 

Khi nào nên sử dụng conflate:

Khi bạn chỉ quan tâm đến giá trị mới nhất.

Trong các tình huống giao diện người dùng (UI) nơi việc hiển thị trạng thái trung gian không cần thiết.

Khi không cần xử lý mọi giá trị được phát.

⏱️ Toán tử Debounce

Toán tử debounce chỉ phát một giá trị sau khi một khoảng thời gian nhất định đã trôi qua mà không có giá trị mới nào được phát.

flow { for (i in 1..5) { emit(i) println("Emitting $i") delay(100) }
}.buffer(2) // Buffer capacity of 2 .collect { value: Int -> println("Collecting $value") delay(300) // Slow collector
} // Output:
// Emitting 1
// Emitting 2
// Emitting 3
// Collecting 1 (t=300ms)
// Collecting 2 (t=600ms)
// Emitting 4
// Emitting 5
// Collecting 3 (t=900ms)
// Collecting 4 (t=1200ms)
// Collecting 5 (t=1500ms) 

Khi nào nên sử dụng debounce:

Cho chức năng tìm kiếm khi người dùng nhập liệu.

Khi xử lý các sự kiện UI nhanh chóng.

Khi bạn muốn chờ một khoảng "thời gian yên tĩnh" trước khi xử lý.

📊 Toán tử Sample

Toán tử sample định kỳ lấy mẫu giá trị mới nhất từ flow tại các khoảng thời gian xác định.

flow { var i = 0 while (i < 10) { emit(i++) delay(50) // Emit every 50ms }
}.sample(100) // Sample every 100ms .collect { value: Int -> println("Sampled value: $value")
} // Output:
// Sampled value: 1 (t=100ms)
// Sampled value: 3 (t=200ms)
// Sampled value: 5 (t=300ms)
// Sampled value: 7 (t=400ms)
// Sampled value: 9 (t=500ms)
// (Only captures the latest value every 100ms)

Khi nào nên sử dụng sample:

Khi bạn cần cập nhật định kỳ tại các khoảng thời gian cố định.

Khi bạn muốn giới hạn tốc độ xử lý dữ liệu.

Comparison and Best Practices

Dưới đây là so sánh nhanh các toán tử này:

Toán tử Hành vi Trường hợp sử dụng
buffer Lưu trữ các giá trị được phát Xử lý tất cả các giá trị, duy trì thứ tự
conflate Chỉ giữ giá trị mới nhất Cập nhật UI, chỉ quan tâm đến giá trị mới nhất
debounce Chờ khoảng thời gian yên tĩnh Tìm kiếm khi nhập liệu, xử lý sự kiện UI nhanh chóng
sample Lấy mẫu định kỳ giá trị mới nhất Cập nhật định kỳ, giới hạn tốc độ xử lý

✅ Kết luận

Hiểu rõ các toán tử Flow này là điều cần thiết để xây dựng các ứng dụng phản ứng hiệu quả:

  • Sử dụng buffer khi bạn cần xử lý tất cả các giá trị và kiểm soát việc sử dụng bộ nhớ.
  • Sử dụng conflate khi chỉ quan tâm đến giá trị mới nhất.
  • Sử dụng debounce khi xử lý các sự kiện nhanh cần có "thời gian giải quyết"
  • Sử dụng sample khi cần cập nhật định kỳ tại các khoảng thời gian cố định.

Chọn operator thích hợp dựa trên trường hợp sử dụng cụ thể của bạn và các yêu cầu về tính đầy đủ, thứ tự và tốc độ xử lý dữ liệu.

Hãy nhớ rằng các toán tử này có thể được kết hợp để tạo ra các quy trình xử lý dữ liệu phức tạp hơn, nhưng hãy cẩn thận để không làm phức tạp quá nhiều quy trình của bạn. Luôn xem xét sự đánh đổi giữa tính đầy đủ của dữ liệu, mức sử dụng bộ nhớ và hiệu quả xử lý.

Link : https://carrion.dev/en/posts/flow-operators-buffer-conflate/

Bình luận

Bài viết tương tự

- vừa được xem lúc

Học Flutter từ cơ bản đến nâng cao. Phần 1: Làm quen cô nàng Flutter

Lời mở đầu. Gần đây, Flutter nổi lên và được Google PR như một xu thế của lập trình di động vậy.

0 0 299

- vừa được xem lúc

Học Flutter từ cơ bản đến nâng cao. Phần 3: Lột trần cô nàng Flutter, BuildContext là gì?

Lời mở đầu. Màn làm quen cô nàng FLutter ở Phần 1 đã gieo rắc vào đầu chúng ta quá nhiều điều bí ẩn về nàng Flutter.

1 1 357

- vừa được xem lúc

[Android] Hiển thị Activity trên màn hình khóa - Show Activity over lock screen

Xin chào các bạn, Hôm nay là 30 tết rồi, ngồi ngắm trời chờ đón giao thừa, trong lúc rảnh rỗi mình quyết định ngồi viết bài sau 1 thời gian vắng bóng. .

0 0 114

- vừa được xem lúc

Tìm hiểu Proguard trong Android

1. Proguard là gì . Cụ thể nó giúp ứng dụng của chúng ta:. .

0 0 108

- vừa được xem lúc

Làm ứng dụng học toán đơn giản với React Native - Phần 6

Chào các bạn một năm mới an khang thịnh vượng, dồi dào sức khỏe. Lại là mình đây Đây là link app mà các bạn đang theo dõi :3 https://play.google.com/store/apps/details?id=com.

0 0 85

- vừa được xem lúc

20 Plugin hữu ích cho Android Studio

1. CodeGlance. Plugin này sẽ nhúng một minimap vào editor cùng với thanh cuộn cũng khá là lớn. Nó sẽ giúp chúng ta xem trước bộ khung của code và cho phép điều hướng đến đoạn code mà ta mong muốn một cách nhanh chóng.

0 0 322