Producer/consumer, pipeline e timeout
Costruisca un semplice producer/consumer , componga pipeline con AsyncSequence e implementi un timeout mettendo in gara un'attività di sleep.
Producer/consumer, pipeline e timeout è una lezione Swift Academy gratuita su CoddyKit. Questa è la lezione 1 di 3. Puoi leggere la lezione completa qui gratuitamente — poi esercitati direttamente nel browser con un editor di codice integrato e un tutor IA disponibile 24/7. Fa parte del percorso di apprendimento Swift Academy, e i tuoi progressi si sincronizzano tra il web e l'app CoddyKit. Il corso Swift Academy include 3 lezioni in totale.
Cosa realizzerà
Questa lezione mostra tre pattern:
- Produttore/consumatore con AsyncStream
- Pipeline usando trasformazioni di AsyncSequence
- Timeout mettendo task in gara in modo cooperativo
Produttore/consumatore di base
AsyncStream collega i produttori basati sul push al consumo pull-based con 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()
}Politica di backpressure
Scelga una bufferingPolicy per gestire la backpressure (scartare il più vecchio, scartare il più recente oppure usare una capacità illimitata per gli stream piccoli).
// 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)
}
}Pipeline con AsyncSequence
AsyncSequence supporta operatori familiari (map, filter, reduce), così può creare pipeline di streaming in modo chiaro.
// 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)
}Fase parallela
Usi i gruppi di task all'interno delle pipeline per le trasformazioni che richiedono molta CPU, quindi riunisca i risultati nell'ordine che preferisce.
// 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"]
}Funzione di supporto per il timeout
Implementi un timeout mettendo l'operazione in gara con un task sleep; annulli quello perdente per evitare lavoro inutile.
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
}
}Pattern del timeout (race)
Verifica rapida: Qual è un buon modo per aggiungere un timeout?
Riepilogo
Riepilogo:
- Usi AsyncStream per il modello produttore/consumatore.
- Componi pipeline di AsyncSequence con map/filter/reduce.
- Implementi i timeout mettendo i task in gara e annullando quello perdente.
Impara Swift con un tutor IA — gratis
Scrivi ed esegui vero codice nel tuo browser, ricevi aiuto istantaneo da un tutor IA disponibile 24/7, e riprendi da dove hai lasciato sul web o nell'app.
- Corsi
- 122
- Lezioni
- 409
Domande Frequenti
La lezione «Producer/consumer, pipeline e timeout» è gratuita?
Sì — il testo completo di «Producer/consumer, pipeline e timeout» è gratuito qui sul web. Per esercitarvi in modo interattivo (un editor di codice integrato e un tutor IA 24/7) e sbloccare il resto del corso Swift Academy, passa a CoddyKit PRO. Il corso Swift Academy include 3 lezioni in totale.
Cosa imparerò in «Producer/consumer, pipeline e timeout»?
Costruisca un semplice producer/consumer , componga pipeline con AsyncSequence e implementi un timeout mettendo in gara un'attività di sleep. Eserciti Swift Academy con codice pratico che esegui direttamente nel browser, e un tutor IA 24/7 risponde alle tue domande mentre lavori sulla lezione.
Ho bisogno di esperienza per iniziare Swift Academy?
Non è richiesta alcuna esperienza precedente. Swift Academy su CoddyKit è strutturato per principianti e studenti avanzati, quindi puoi iniziare da qui o dall'inizio e procedere al tuo ritmo. Questa è la lezione 1 di 3.
Quanto tempo richiede la lezione «Producer/consumer, pipeline e timeout»?
La maggior parte delle lezioni CoddyKit richiede circa 5–10 minuti. Ogni lezione è breve e interattiva, quindi fai progressi costanti e riprendi esattamente da dove hai lasciato su web e app.
Posso scrivere ed eseguire codice in questa lezione Swift Academy?
Sì. Ogni lezione Swift Academy include un editor di codice integrato, quindi scrivi ed esegui codice reale direttamente nel tuo browser e ricevi feedback istantaneo dall'IA — nessuna configurazione locale necessaria.
Tutte le lezioni di questo corso
- Producer/consumer, pipeline e timeout
- Collegare callback legacy/Combine ad async/await
- Testare il codice async (XCTest)