Produsen/konsumen, alur, batas waktu
Bangun produsen/konsumen sederhana, susun alur dengan AsyncSequence, dan terapkan batas waktu dengan mengadu tugas tidur.
Produsen/konsumen, alur, batas waktu adalah pelajaran Swift Academy gratis di CoddyKit. Ini adalah pelajaran 1 dari 3. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Swift Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Swift Academy mencakup 3 pelajaran total.
Yang akan Anda buat
Pelajaran ini menunjukkan tiga pola:
- Produsen/konsumen dengan AsyncStream
- Alur menggunakan transformasi AsyncSequence
- Batas waktu dengan mengadu task secara kooperatif
Dasar produsen/konsumen
AsyncStream menjembatani produsen bergaya push dengan konsumsi berbasis pull menggunakan for await.
// Producer pushes values; consumer iterates them asynchronously.
func makeNumbers(count: Int) -> AsyncStream<Int> {
AsyncStream { continuation in
Task {
for i in 1...count {
continuation.yield(i)
try? await Task.sleep(nanoseconds: 40_000_000) // ~40ms
}
continuation.finish()
}
}
}
Task {
let stream = makeNumbers(count: 5)
for await n in stream {
print("consume:", n)
}
print("done") // after finish()
}Kebijakan tekanan balik
Pilih bufferingPolicy untuk mengelola tekanan balik (buang yang paling lama, buang yang paling baru, atau tanpa batas untuk aliran kecil).
// Use a limited buffering policy to avoid memory spikes.
func makeBufferedNumbers(limit: Int) -> AsyncStream<Int> {
AsyncStream(bufferingPolicy: .bufferingOldest(limit)) { cont in
Task {
for i in 1...20 {
cont.yield(i)
// Producer is fast; buffer prevents unbounded growth
}
cont.finish()
}
}
}
Task {
let s = makeBufferedNumbers(limit: 5)
for await n in s {
// Simulate a slow consumer
try? await Task.sleep(nanoseconds: 60_000_000)
print("got:", n)
}
}Alur dengan AsyncSequence
AsyncSequence mendukung operator yang sudah dikenal (map, filter, reduce) sehingga Anda dapat membangun alur streaming dengan jelas.
// Compose a pipeline: map -> filter -> reduce over an AsyncSequence.
func numbers(_ n: Int) -> AsyncStream<Int> {
AsyncStream { cont in
Task {
for i in 1...n { cont.yield(i) }
cont.finish()
}
}
}
Task {
let evensSquaredSum = await numbers(10)
.map { $0 * $0 }
.filter { $0.isMultiple(of: 2) }
.reduce(0, +)
print("sum:", evensSquaredSum) // 220 (4+16+36+64+100)
}Tahap paralel
Gunakan kelompok task di dalam alur untuk transformasi yang terikat CPU, lalu gabungkan kembali hasilnya sesuai urutan yang Anda inginkan.
// Fan-out/fan-in: process items concurrently, then merge.
// Here we use a task group to transform elements in parallel.
func parallelUppercased(_ input: [String]) async -> [String] {
await withTaskGroup(of: String.self) { group in
for s in input {
group.addTask {
try? await Task.sleep(nanoseconds: 30_000_000)
return s.uppercased()
}
}
return await group.reduce(into: [String]()) { $0.append($1) }
}
}
Task {
let out = await parallelUppercased(["a","bb","ccc"])
print(out) // ["A","BB","CCC"]
}Pembantu batas waktu
Terapkan batas waktu dengan mengadu operasi melawan task sleep; lakukan cancel pada task yang kalah untuk menghemat pekerjaan.
enum TimeoutError: Error { case timedOut }
func withTimeout<T>(
seconds: Double,
operation: @escaping () async throws -> T
) async throws -> T {
try await withThrowingTaskGroup(of: T.self) { group in
// Child 1: actual work
group.addTask { try await operation() }
// Child 2: the timer
group.addTask {
try await Task.sleep(nanoseconds: UInt64(seconds * 1_000_000_000))
throw TimeoutError.timedOut
}
// First child to finish wins; cancel the rest
let result = try await group.next()!
group.cancelAll()
return result
}
}
// Demo
func slowFetch() async throws -> String {
try await Task.sleep(nanoseconds: 300_000_000) // 300ms
return "OK"
}
Task {
do {
let v = try await withTimeout(seconds: 0.1) { try await slowFetch() }
print("value:", v)
} catch {
print("timeout:", error) // expected
}
}Pola batas waktu (perlombaan)
Pemeriksaan singkat: Apa cara yang baik untuk menambahkan batas waktu?
Ringkasan
Ringkasan:
- Gunakan AsyncStream untuk produsen/konsumen.
- Susun alur AsyncSequence dengan map/filter/reduce.
- Terapkan batas waktu dengan mengadu task dan melakukan cancel pada task yang kalah.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Produsen/konsumen, alur, batas waktu” gratis?
Ya — teks lengkap “Produsen/konsumen, alur, batas waktu” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Swift Academy, upgrade ke CoddyKit PRO. Kursus Swift Academy mencakup 3 pelajaran total.
Apa yang akan aku pelajari di “Produsen/konsumen, alur, batas waktu”?
Bangun produsen/konsumen sederhana, susun alur dengan AsyncSequence, dan terapkan batas waktu dengan mengadu tugas tidur. Kamu berlatih Swift Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Swift Academy?
Tidak diperlukan pengalaman sebelumnya. Swift Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 1 dari 3.
Berapa lama pelajaran “Produsen/konsumen, alur, batas waktu” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Swift Academy ini?
Ya. Setiap pelajaran Swift Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Produsen/konsumen, alur, batas waktu
- Menjembatani callback lama/Combine ke async/await
- Menguji kode asinkron (XCTest)