Section 6/161 menit
6. Operator Time-based
6. Operator Time-based
Semua operator time-based memerlukan iOS 16+ karena menggunakan Clock protocol.
debounce
Menunggu sampai tidak ada input baru selama interval tertentu sebelum meneruskan elemen. Berguna untuk search field, scroll position, dsb.
swift
// debounce: tunggu 300ms sepi sebelum proses
let searchChannel = AsyncChannel<String>()
Task {
for await query in searchChannel.debounce(for: .milliseconds(300)) {
// Hanya dipanggil setelah user berhenti mengetik 300ms
let results = try await searchAPI(query: query)
await updateResults(results)
}
}
// Keyboard input
func onKeyPress(_ text: String) async {
await searchChannel.send(text) // kirim setiap keystroke
// debounce memfilter burst input otomatis
}
throttle
Membatasi laju emisi — maksimum satu elemen per interval. Berbeda dari debounce: throttle tidak menunggu input berhenti, tapi membatasi frekuensi output.
swift
// throttle: maksimum satu update per detik
let locationUpdates = locationManager.coordinateStream()
// reducing: bagaimana menggabungkan nilai yang di-throttle
// (ambil nilai terbaru dari burst)
let throttled = locationUpdates.throttle(
for: .seconds(1),
reducing: { _, latest in latest } // ambil nilai paling baru
)
for await coordinate in throttled {
// Dipanggil maksimum sekali per detik, meski GPS update lebih sering
await updateMapPin(at: coordinate)
}
swift
// throttle dengan reducer berbeda: ambil nilai pertama (bukan terakhir)
let firstOnly = stream.throttle(
for: .seconds(1),
reducing: { first, _ in first }
)
// throttle untuk counter: jumlahkan semua nilai dalam window
let summed = intStream.throttle(
for: .seconds(1),
reducing: { acc, new in acc + new }
)
chunked(by: .repeating(every:))
Mengumpulkan elemen dalam window waktu tertentu, lalu emit sebagai array/collection.
swift
// chunked by time: kumpulkan 5 detik, proses sekaligus
let sensorReadings = sensorStream() // AsyncSequence<SensorReading>
for await chunk in sensorReadings.chunked(by: .repeating(every: .seconds(5))) {
// chunk berisi semua reading dalam 5 detik terakhir
let average = chunk.map(\.value).reduce(0, +) / Double(chunk.count)
await recordAverageReading(average)
}
Kombinasi Time + Count
swift
// Emit chunk ketika 100 elemen ATAU 10 detik berlalu, mana yang lebih dulu
let events = eventStream()
// Gunakan race condition antara count dan duration
for await chunk in events.chunks(ofCount: 100) {
await uploadBatch(Array(chunk))
}
// Atau dengan waktu saja:
for await chunk in events.chunked(by: .repeating(every: .seconds(10))) {
await uploadBatch(Array(chunk))
}