RxSwift — คืออะไร ความสามารถและการเขียนโปรแกรมเชิงปฏิกิริยา

ผู้แต่ง: IT Sectr เผยแพร่เมื่อ: 2026-05-03 เวลาอ่าน: 10 นาที

RxSwift คือไลบรารีการเขียนโปรแกรมเชิงปฏิกิริยาสำหรับ iOS ที่ใช้รูปแบบ Observable และตัวดำเนินการเชิงฟังก์ชันสำหรับทำงานกับสตรีมข้อมูลแบบอะซิงโครนัส โดยนำแนวคิดของ ReactiveX (Rx) มาสู่ภาษา Swift โดยมี API แบบรวมสำหรับจัดการเหตุการณ์จาก UI คำขอเครือข่าย ฐานข้อมูลและตัวจับเวลา ตามข้อมูลของ ReactiveX, 2025 ไลบรารีนี้ถูกใช้ในโครงการมากกว่า 60,000 โครงการบน GitHub และยังคงเป็นมาตรฐานการเขียนโปรแกรมเชิงปฏิกิริยาสำหรับ Swift จนกระทั่ง Combine ดั้งเดิมถือกำเนิดขึ้น RxSwift แทนที่ delegates closures และการแจ้งเตือนด้วยห่วงโซ่การประมวลผลเหตุการณ์เดียว

ประเด็นสำคัญ

  • RxSwift — การนำ ReactiveX ไปใช้สำหรับ Swift บนพื้นฐานของรูปแบบ Observable และห่วงโซ่ตัวดำเนินการ
  • Observable — แหล่งที่มาของเหตุการณ์แบบอะซิงโครนัสที่สามารถเสร็จสมบูรณ์สำเร็จ มีข้อผิดพลาดหรือไม่สิ้นสุด
  • Subject — ลูกผสมของ Observable และ Observer ที่อนุญาตให้ส่งเหตุการณ์ไปยังสตรีมด้วยตนเอง
  • Schedulers ควบคุมว่าการสมัครสมาชิก การสังเกตและการประมวลผลเหตุการณ์เกิดขึ้นบนเธรดใด
  • ตัวดำเนินการ map, flatMap, filter, combineLatest เปลี่ยนรูปและรวมสตรีมโดยไม่มีสภาวะการแข่งขัน

RxSwift คืออะไร?

RxSwift คือพอร์ต Swift ของไลบรารี ReactiveX (Rx) ที่สร้างโดย Microsoft สำหรับ .NET ในปี 2012 แนวคิดหลักของ Rx คือการแสดงแหล่งข้อมูลแบบอะซิงโครนัสใดๆ เป็นลำดับ Observable ซึ่งสามารถใช้ตัวดำเนินการเชิงฟังก์ชันได้ ในการพัฒนา iOS RxSwift ใช้สำหรับเชื่อมโยงเหตุการณ์ UI (การกดปุ่ม การป้อนข้อความ ท่าทาง) เข้ากับตรรกะของแอปพลิเคชันโดยไม่มี delegates ที่ชัดเจนและ target-action

ไลบรารีประกอบด้วยสามโมดูล: RxSwift (แกนกลาง — Observable, Operator, Scheduler), RxCocoa (การรวม UIKit — ส่วนขยาย rx สำหรับ UIButton, UITextField, UITableView) และ RxRelay (Subject ที่ไม่มีเหตุการณ์สิ้นสุด) การแยกนี้ทำให้สามารถใช้แกนกลางใน Swift ฝั่งเซิร์ฟเวอร์และการทดสอบ โดยเชื่อมต่อตัวหุ้ม UI สำหรับแอปพลิเคชัน iOS เท่านั้น

จากการสำรวจของ Stack Overflow, 2025 พบว่า RxSwift อยู่ใน 5 อันดับแรกของไลบรารีบุคคลที่สามที่ใช้มากที่สุดสำหรับ iOS เหตุผลหลักของความนิยมคือการจัดการรูปแบบอะซิงโครนัสทั้งหมดอย่างสม่ำเสมอ: คำขอเครือข่ายผ่าน URLSession แอนิเมชันผ่าน UIViewPropertyAnimator การแจ้งเตือนผ่าน NotificationCenter และ delegates ผ่าน DelegateProxy — ทั้งหมดนี้สรุปเป็น Observable ที่มีวงจรชีวิตที่คาดเดาได้

ปรัชญาการเขียนโปรแกรมเชิงปฏิกิริยา

การเขียนโปรแกรมเชิงปฏิกิริยา เป็นกระบวนทัศน์ที่โปรแกรมตอบสนองต่อการเปลี่ยนแปลงข้อมูลแทนที่จะสอบถามข้อมูล แทนที่จะเขียน “รับข้อมูล → ประมวลผล → อัปเดต UI” นักพัฒนาจะอธิบายห่วงโซ่การเปลี่ยนแปลง: “เมื่อข้อมูลเปลี่ยน ให้ใช้ตัวกรอง จากนั้น map จากนั้นอัปเดต UI” RxSwift ใช้กระบวนทัศน์นี้ผ่านห่วงโซ่ Observable ที่มีการดำเนินการแบบขี้เกียจ — จะไม่มีอะไรเกิดขึ้นจนกว่าจะมีผู้สมัครสมาชิกปรากฏขึ้น

ส่วนประกอบหลักของ RxSwift: Observable, Subject, Disposable

Observable เป็นชนิดพื้นฐานของ RxSwift ที่แสดงลำดับของเหตุการณ์ในช่วงเวลา Observable สามารถส่งเหตุการณ์สามประเภท: next (ค่าใหม่), error (ข้อผิดพลาดที่สิ้นสุดสตรีม) และ completed (การเสร็จสมบูรณ์สำเร็จ) มี Observable แบบจำกัด (เสร็จสมบูรณ์หลังจากส่งค่าทั้งหมด) และ Observable แบบไม่จำกัด (เช่น เหตุการณ์ UI — ไม่เคยเสร็จสมบูรณ์)

Observable และวงจรชีวิตของมัน

วงจรชีวิต ของ Observable ประกอบด้วยสามขั้นตอน: การสร้าง (create, just, from), การเปลี่ยนรูป (ตัวดำเนินการ map, filter, flatMap) และการสมัครสมาชิก (subscribe) หากไม่มีการสมัครสมาชิก Observable จะไม่ดำเนินการใดๆ — มันเป็นลำดับแบบขี้เกียจ หลังจากการสมัครสมาชิก Observable จะเริ่มส่งเหตุการณ์ไปยังผู้สมัครสมาชิกจนกว่าจะเสร็จสมบูรณ์หรือผู้สมัครสมาชิกยกเลิกการสมัครผ่าน Disposable

swift
import RxSwift

// การสร้าง Observable จากอาร์เรย์
let numbers = Observable.from([1, 2, 3, 4, 5])

// การเปลี่ยนรูปผ่านตัวดำเนินการ
let squared = numbers
    .filter { $0 % 2 == 0 }
    .map { $0 * $0 }

// การสมัครสมาชิกพร้อมจัดการเหตุการณ์
let disposable = squared
    .subscribe(onNext: { print($0) },
               onError: { print("Error: \($0)") },
               onCompleted: { print("Done") })

Subject เป็นชนิดที่เป็นทั้ง Observable (สามารถสมัครสมาชิกได้) และ Observer (สามารถส่งเหตุการณ์ไปยังมันได้) RxSwift มี Subject สี่ประเภท: PublishSubject (เฉพาะเหตุการณ์ใหม่), BehaviorSubject (มีค่าเริ่มต้น), ReplaySubject (บัฟเฟอร์ N เหตุการณ์ล่าสุด) และ AsyncSubject (เฉพาะค่าสุดท้ายก่อนเสร็จสมบูรณ์) Subject มีประโยชน์สำหรับการรวมโค้ดแบบ Imperative (closures, delegates) เข้ากับห่วงโซ่เชิงปฏิกิริยา

Disposable คือโทเค็นการยกเลิกการสมัครสมาชิก เมื่อผู้สมัครสมาชิกไม่ต้องการรับเหตุการณ์อีกต่อไป มันจะเรียก disposable.dispose() ในทางปฏิบัติ จะใช้ DisposeBag: ชุดของ Disposable ที่ยกเลิกการสมัครสมาชิกทั้งหมดโดยอัตโนมัติเมื่อยกเลิกการเริ่มต้นเจ้าของ (เช่น UIViewController) ซึ่งป้องกันการรั่วไหลของหน่วยความจำที่หลีกเลี่ยงไม่ได้เมื่อจัดการการสมัครสมาชิกด้วยตนเอง

ประเภท Subjectค่าเริ่มต้นส่งซ้ำให้ผู้สมัครสมาชิกกรณีใช้งาน
PublishSubjectไม่มีเฉพาะเหตุการณ์ใหม่เหตุการณ์ UI การแจ้งเตือนที่หายาก
BehaviorSubjectมีล่าสุด + ใหม่สถานะ สตรีมข้อมูล
ReplaySubjectไม่มีบัฟเฟอร์ N + ใหม่การแคชประวัติ
AsyncSubjectไม่มีเฉพาะล่าสุดงานคำนวณ
PublishRelayไม่มีเฉพาะใหม่ไม่มี error/completed

ตัวดำเนินการเปลี่ยนรูปและกรองสตรีม

ตัวดำเนินการ ใน RxSwift คือฟังก์ชันที่รับ Observable หนึ่งและส่งคืน Observable อีกตัว โดยเปลี่ยนรูปสตรีมข้อมูล การรวมตัวดำเนินการทำให้นักพัฒนาสร้างห่วงโซ่การประมวลผลแบบ Declarative โดยไม่มีตัวแปรกลางและสภาวะการแข่งขัน ตัวดำเนินการทั้งหมดขี้เกียจ: ห่วงโซ่ถูกสร้างขึ้นเมื่ออธิบายและดำเนินการเมื่อสมัครสมาชิก

ตัวดำเนินการเปลี่ยนรูป เปลี่ยนแต่ละเหตุการณ์ในสตรีม map ใช้ฟังก์ชันกับแต่ละองค์ประกอบ flatMap คลาย Observable จากแต่ละองค์ประกอบเป็นสตรีมเรียบเดียว scan สะสมผลลัพธ์ระหว่างกลาง (คล้าย reduce แต่ปล่อยแต่ละขั้นตอน) buffer จัดกลุ่มองค์ประกอบตามเวลาหรือจำนวน window แบ่งสตรีมเป็น Observable ที่ซ้อนกันตามหน้าต่าง

swift
// ตัวอย่างห่วงโซ่ตัวดำเนินการ: ค้นหาด้วย debounce
searchTextField.rx.text
    .orEmpty
    .debounce(.milliseconds(300), scheduler: MainScheduler.instance)
    .distinctUntilChanged()
    .flatMapLatest { query -> Observable<[String]> in
        return apiService.search(query)
    }
    .bind(to: tableView.rx.items(cellIdentifier: "Cell")) { _, item, cell in
        cell.textLabel?.text = item
    }
    .disposed(by: disposeBag)

ตัวดำเนินการกรอง อนุญาตเฉพาะเหตุการณ์ที่ตรงตามเงื่อนไข filter กรองตามภาคแสดง distinctUntilChanged อนุญาตเฉพาะค่าที่แตกต่างจากค่าก่อนหน้า take และ takeWhile จำกัดจำนวนเหตุการณ์ skip และ skipWhile ข้าม N เหตุการณ์แรกหรือเหตุการณ์จนกว่าเงื่อนไขจะเป็นจริง สำหรับการจัดการข้อผิดพลาด จะใช้ catchError (สกัดกั้นและแทนที่) และ retry (ลองลำดับใหม่เมื่อเกิดข้อผิดพลาด)

ตัวดำเนินการรวม รวม Observable หลายตัวเป็นหนึ่งเดียว combineLatest รวมค่าล่าสุดจากหลายสตรีมเป็น tuple zip จับคู่องค์ประกอบที่มีดัชนีเดียวกัน merge รวมหลายสตรีมเป็นหนึ่งตามลำดับการมาถึงของเหตุการณ์ withLatestFrom รวมเหตุการณ์จากสตรีมหลักกับค่าล่าสุดจากสตรีมอื่น — มีประโยชน์สำหรับเหตุการณ์ UI ที่มีสถานะปัจจุบัน

หมวดหมู่ตัวดำเนินการคำอธิบาย
เปลี่ยนรูปmapเปลี่ยนรูปแต่ละค่าผ่านฟังก์ชัน
เปลี่ยนรูปflatMapคลาย Observable ที่ซ้อนกันเป็นสตรีมเรียบ
กรองfilterอนุญาตค่าตามภาคแสดง
กรองdistinctUntilChangedอนุญาตเฉพาะค่าที่เปลี่ยนแปลง
รวมcombineLatestรวมค่าล่าสุดจาก 2+ สตรีม
รวมzipจับคู่องค์ประกอบตามดัชนี
ควบคุมdebounceหน่วงเหตุการณ์จนกว่าสตรีมหยุดชั่วคราว
ควบคุมtakeรับ N เหตุการณ์แรกและสิ้นสุดสตรีม

Schedulers และการจัดการเธรด

Scheduler ใน RxSwift คือการทำให้เป็นนามธรรมเหนือเธรดการดำเนินการ (หรือคิว) Scheduler กำหนดว่าเหตุการณ์ การเปลี่ยนรูปและการสมัครสมาชิกจะดำเนินการบนเธรดใด ต่างจาก GCD ที่นักพัฒนาระบุ DispatchQueue อย่างชัดเจน RxSwift ใช้สองพารามิเตอร์: subscribeOn (เธรดใดที่ Observable ดำเนินการ) และ observeOn (เธรดใดที่เรียกผู้สมัครสมาชิก)

MainScheduler และ BackgroundScheduler

MainScheduler ดำเนินการโค้ดบนเธรดหลัก — จำเป็นสำหรับการอัปเดต UIKit (การเปลี่ยนแปลง UI ทั้งหมดต้องเกิดขึ้นบนเธรดหลัก) SerialDispatchQueueScheduler ห่อหุ้มคิว GCD แบบอนุกรม ConcurrentDispatchQueueScheduler ห่อหุ้มคิวแบบพร้อมกัน สำหรับงานเบื้องหลัง ใช้ ConcurrentDispatchQueueScheduler ด้วย qos: .background หรือ .utility

swift
// รูปแบบทั่วไป: งานเบื้องหลัง + UI บน main
apiService.fetchData()
    .subscribeOn(ConcurrentDispatchQueueScheduler(qos: .background))
    .observeOn(MainScheduler.instance)
    .subscribe(onNext: { data in
        self.tableView.reloadData()
        self.loadingIndicator.stopAnimating()
    })
    .disposed(by: disposeBag)

การใช้ Scheduler อย่างถูกต้องป้องกันการบล็อก UI ระหว่างคำขอเครือข่ายและการคำนวณหนัก subscribeOn ส่งผลต่อต้นน้ำทั้งหมด (ตัวดำเนินการทั้งหมดก่อน observeOn ดำเนินการบนตัวกำหนดตารางเวลาที่ระบุ) observeOn สลับปลายน้ำ — ตัวดำเนินการทั้งหมดหลัง observeOn ดำเนินการบนตัวกำหนดตารางเวลาที่ระบุ ห่วงโซ่อาจมีหลาย observeOn สำหรับสลับระหว่างเธรดในขั้นตอนการเปลี่ยนรูปต่างๆ

SerialDispatchQueueScheduler รับประกันการประมวลผลเหตุการณ์ตามลำดับ ซึ่งสำคัญสำหรับความปลอดภัยของเธรดของทรัพยากรที่ใช้ร่วมกัน สำหรับการดำเนินการที่มีภาระสูง (การประมวลผลภาพ การแยกวิเคราะห์ JSON) ให้ใช้ ConcurrentDispatchQueueScheduler — RxSwift จะรักษาลำดับเหตุการณ์ภายใน Observable เดียว แต่ Observable ต่างๆ อาจถูกประมวลผลแบบขนาน

การประยุกต์ใช้ RxSwift ใน iOS

RxSwift ในโครงการ iOS มักใช้สำหรับเชื่อมโยง UI กับข้อมูลผ่านห่วงโซ่เชิงปฏิกิริยา RxCocoa ให้ส่วนขยาย rx สำหรับส่วนประกอบ UIKit มาตรฐานทั้งหมด: rx.tap สำหรับ UIButton, rx.text สำหรับ UITextField, rx.selectedRow สำหรับ UIPickerView ซึ่งช่วยให้ละทิ้ง @IBAction และ delegates แทนที่ด้วยการสมัครสมาชิกแบบ Declarative

RxSwift ร่วมกับ MVVM

MVVM (Model-View-ViewModel) เป็นรูปแบบสถาปัตยกรรมที่ ViewModel จัดการสถานะและตรรกะทางธุรกิจ และ View สมัครสมาชิกคุณสมบัติเชิงปฏิกิริยาของ ViewModel RxSwift เข้ากันได้อย่างสมบูรณ์กับ MVVM: ViewModel เผยแพร่ Observable หรือ Driver สำหรับข้อมูล View สมัครสมาชิกผ่าน bind ViewModel ไม่มีการอ้างอิงถึง View — มันส่งคืน Observable ที่ View ใช้

swift
class LoginViewModel {
    let email = BehaviorRelay<String>(value: "")
    let password = BehaviorRelay<String>(value: "")

    var isFormValid: Observable<Bool> {
        return Observable
            .combineLatest(email, password) {
                !$0.isEmpty && $0.contains("@") && $1.count >= 6
            }
    }
}

// ใน ViewController:
viewModel.isFormValid
    .bind(to: loginButton.rx.isEnabled)
    .disposed(by: disposeBag)

คำขอเครือข่ายเป็นกรณีการใช้งานที่พบบ่อยเป็นอันดับสองของ RxSwift URLSession.rx.response ห่อหุ้มคำขอ HTTP ใน Observable ที่ส่งคืน (response, data) เมื่อสำเร็จหรือ error เมื่อล้มเหลว เมื่อรวมกับ Codable และตัวดำเนินการ map จะได้ชั้น API เชิงปฏิกิริยาที่กะทัดรัด: Observable<MyModel> โดยไม่มี callbacks และการจัดการข้อผิดพลาดในแต่ละวิธี เมื่อเกิดข้อผิดพลาดเครือข่าย ตัวดำเนินการ retry(3) จะลองคำขอใหม่โดยอัตโนมัติสามครั้งด้วยการหน่วงเวลาแบบเอกซ์โปเนนเชียล

RxSwift vs Combine

Combine เป็น framework ดั้งเดิมของ Apple ที่เปิดตัวใน iOS 13 โดยแก้ปัญหาเดียวกันกับ RxSwift: การทำงานกับเหตุการณ์แบบอะซิงโครนัสผ่าน Publisher, Subscriber และตัวดำเนินการ อย่างไรก็ตาม Combine มีความแตกต่างสำคัญ: การกำหนดชนิดข้อผิดพลาดที่เข้มงวดผ่านชนิด Failure การรองรับ Swift Concurrency (async/await) ในตัว และการรวมกับ SwiftUI ผ่าน @Published และ ObservableObject

RxSwift ชนะในด้านความเข้ากันได้ย้อนหลัง — รองรับ iOS 8+ ในขณะที่ Combine ต้องการ iOS 13+ RxSwift มีระบบนิเวศส่วนขยายของบุคคลที่สามที่สมบูรณ์กว่า (RxDataSources, RxGesture, RxAnimated) และเอกสารตัวดำเนินการโดยละเอียด สำหรับโครงการที่รองรับ iOS เวอร์ชันเก่า RxSwift ยังคงเป็นตัวเลือกเดียว

สำหรับโครงการใหม่บน iOS 13+ Apple แนะนำ Combine มันถูกรวมเข้ากับ SwiftUI อย่างแน่นหนา มีขนาดไบนารีที่เล็กกว่าและการสนับสนุนอย่างเป็นทางการ อย่างไรก็ตาม การย้ายโค้ด RxSwift ที่มีอยู่ไปยัง Combine ต้องเขียน Observable → Publisher ใหม่ทั้งหมด และระบบนิเวศ RxCocoa ไม่มีสิ่งที่เทียบเท่า Combine อย่างสมบูรณ์ — UIKit ไม่มี Publisher ดั้งเดิมสำหรับส่วนประกอบ UI ทั้งหมด

คุณลักษณะRxSwiftCombine
iOS ขั้นต่ำiOS 8+iOS 13+
ชนิดข้อผิดพลาดError (ใดๆ)Generic Failure
ส่วนขยาย UIRxCocoa (UIKit, AppKit)@Published (SwiftUI)
ตัวดำเนินการ400+ ตัวดำเนินการ~100 ตัวดำเนินการ
Swift Concurrencyผ่านบริดจ์รองรับดั้งเดิม
สถานะบุคคลที่สามApple อย่างเป็นทางการ

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

ความแตกต่างระหว่าง Observable และ Subject ใน RxSwift คืออะไร?

Observable คือแหล่งที่มาของเหตุการณ์ที่มีการดำเนินการแบบขี้เกียจ Subject เป็นทั้ง Observable และ Observer — คุณสามารถสมัครสมาชิกและส่งเหตุการณ์ใหม่ด้วยตนเอง Subject มีประโยชน์สำหรับการรวมโค้ดแบบ Imperative เข้ากับห่วงโซ่เชิงปฏิกิริยา

เมื่อใดควรใช้ RxSwift แทน Combine?

RxSwift ถูกเลือกเมื่อต้องการรองรับ iOS 11-12 เมื่อมีโค้ดเบส RxSwift ที่มีอยู่ หรือเมื่อต้องการระบบนิเวศตัวดำเนินการที่สมบูรณ์ (400+ เทียบกับ ~100 ใน Combine) สำหรับโครงการใหม่บน iOS 13+ ควรเลือก Combine

DisposeBag คืออะไรและทำไมจึงจำเป็น?

DisposeBag คือชุดของโทเค็น Disposable ที่ยกเลิกการสมัครสมาชิกทั้งหมดโดยอัตโนมัติเมื่อยกเลิกการเริ่มต้นเจ้าของ หากไม่มี DisposeBag การสมัครสมาชิกจะสร้างการอ้างอิงแบบ strong ไปยัง closure ซึ่งนำไปสู่การรั่วไหลของหน่วยความจำเมื่อ UIViewController ถูกทำลาย

วิธีการจัดการข้อผิดพลาดใน RxSwift?

ใช้ catchError เพื่อแทนที่ข้อผิดพลาดด้วยค่าเริ่มต้น retry เพื่อลองดำเนินการ Observable อีกครั้ง materialize เพื่อแปลงข้อผิดพลาดเป็นเหตุการณ์ ในชั้น UI Driver และ Signal จะไม่ส่งข้อผิดพลาด — พวกมันถูกจัดการภายใน

Driver แตกต่างจาก Observable ใน RxCocoa อย่างไร?

Driver เป็น Observable ชนิดพิเศษที่รับประกันการดำเนินการบน MainScheduler การไม่มีข้อผิดพลาดและการแบ่งปันทรัพยากร Driver รับประกันว่าการอัปเดต UI เกิดขึ้นบนเธรดหลัก Observable ไม่ได้ให้การรับประกันดังกล่าว — จำเป็นต้องมี observeOn

สรุป

  • RxSwift คือไลบรารีการเขียนโปรแกรมเชิงปฏิกิริยาสำหรับ iOS ที่ใช้รูปแบบ Observable และตัวดำเนินการเปลี่ยนรูป 400+ ตัว
  • Observable, Subject, Disposable เป็นสามชนิดพื้นฐานที่สร้างรากฐานของห่วงโซ่เชิงปฏิกิริยาทั้งหมด
  • ตัวดำเนินการ map, flatMap, filter, combineLatest, debounce ช่วยสร้างห่วงโซ่แบบ Declarative โดยไม่มีสภาวะการแข่งขัน
  • Schedulers (subscribeOn / observeOn) จัดการเธรดการดำเนินการ ป้องกันการบล็อก UI
  • RxCocoa ให้ส่วนขยาย rx สำหรับ UIKit แทนที่ delegates และ target-action ด้วยการสมัครสมาชิกเชิงปฏิกิริยา
  • Combine เป็นทางเลือกดั้งเดิมของ Apple สำหรับ iOS 13+ แต่ RxSwift ยังคงมีความเกี่ยวข้องสำหรับเวอร์ชันเก่า

เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร

IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ

ปรึกษาโครงการ

อ่านเพิ่มเติม