0Pricing
Swift Academy · บทเรียน

ผู้ผลิต/ผู้บริโภค สายงาน และการหมดเวลา

สร้าง ผู้ผลิต/ผู้บริโภค อย่างง่าย ประกอบ สายงาน ด้วย AsyncSequence และใช้การแข่งกับงาน sleep เพื่อสร้าง การหมดเวลา

ผู้ผลิต/ผู้บริโภค สายงาน และการหมดเวลา เป็นบทเรียน Swift Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 3 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Swift Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Swift Academy มีบทเรียนทั้งหมด 3 บทเรียน

สิ่งที่จะสร้าง

บทเรียนนี้แสดงรูปแบบสามประการ:

  • ผู้ผลิต/ผู้บริโภค ด้วย AsyncStream
  • กระบวนการประมวลผลต่อเนื่อง โดยใช้การแปลงของ AsyncSequence
  • การหมดเวลา ด้วยการแข่งกันของงานแบบร่วมมือกัน

ผู้ผลิตและผู้บริโภคเบื้องต้น

AsyncStream เชื่อมผู้ผลิตแบบผลักเข้ากับการบริโภคแบบดึงด้วย การวนรอ

// 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()
}

นโยบายควบคุมแรงดันย้อนกลับ

เลือก bufferingPolicy เพื่อจัดการแรงดันย้อนกลับ (ทิ้งข้อมูลเก่าสุด ทิ้งข้อมูลใหม่สุด หรือไม่จำกัดขนาดสำหรับสตรีมขนาดเล็ก)

// 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)
    }
}

กระบวนการประมวลผลด้วย AsyncSequence

AsyncSequence รองรับตัวดำเนินการที่คุ้นเคย (เช่น การแปลง การกรอง และ reduce) คุณจึงสร้าง กระบวนการประมวลผลแบบกระแสข้อมูลได้อย่างชัดเจน

// 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)
}

ขั้นตอนแบบขนาน

ใช้ กลุ่มงาน ภายในกระบวนการประมวลผลสำหรับการแปลงข้อมูลที่ใช้ CPU จากนั้นรวมผลลัพธ์กลับตามลำดับที่ต้องการ

// 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"]
}

ตัวช่วยจัดการการหมดเวลา

ใช้การแข่งการทำงานกับงาน sleep เพื่อจัดการ การหมดเวลา จากนั้นใช้ cancel กับฝ่ายที่แพ้เพื่อประหยัดงาน

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
    }
}

รูปแบบการหมดเวลา (การแข่งกัน)

ตรวจสอบสั้น ๆ: วิธีที่ดีในการเพิ่มการหมดเวลาคืออะไร

สรุปทบทวน

สรุปทบทวน:

  • ใช้ AsyncStream สำหรับผู้ผลิตและผู้บริโภค
  • ประกอบกระบวนการประมวลผลของ AsyncSequence ด้วยการแปลง/กรอง/reduce
  • ใช้การแข่งกันของงานและยกเลิกฝ่ายที่แพ้เพื่อจัดการ การหมดเวลา

คำถามที่พบบ่อย

บทเรียน “ผู้ผลิต/ผู้บริโภค สายงาน และการหมดเวลา” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ผู้ผลิต/ผู้บริโภค สายงาน และการหมดเวลา” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Swift Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Swift Academy มีบทเรียนทั้งหมด 3 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “ผู้ผลิต/ผู้บริโภค สายงาน และการหมดเวลา”

สร้าง ผู้ผลิต/ผู้บริโภค อย่างง่าย ประกอบ สายงาน ด้วย AsyncSequence และใช้การแข่งกับงาน sleep เพื่อสร้าง การหมดเวลา คุณปฏิบัติ Swift Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Swift Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Swift Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 3 บทเรียน

บทเรียน “ผู้ผลิต/ผู้บริโภค สายงาน และการหมดเวลา” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Swift Academy นี้ได้ไหม

ได้ บทเรียน Swift Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ผู้ผลิต/ผู้บริโภค สายงาน และการหมดเวลา
  2. การเชื่อมโค้ดเรียกกลับเดิม/Combine เข้ากับ async/await
  3. การทดสอบโค้ด async (XCTest)
← กลับไปที่ Swift Academy