SwiftUI Firestore รอสำหรับการโหลดข้อมูล

0

คำถาม

ฉันกำลังมีปัญหากำลังรับ Firestore getdocument ข้อมูลก่อนมุมมอบความสนใจ ฉันรู้ว่ามันคืนค่าจากหลายการตรวจสอบและมันอาจจะเป็นปัญหากับวิธีที่ฉันรับมือกับการ asynchronous ฟังก์ชัน.

ของฉันสามตัวแปรที่ฉันกำลังพยายามเรียบร้อย

@Published var numParticipants = 0
@Published var totalAnswered = 0
@Published var showResults = false

นี่เป็นครั้งแรกที่ฟังก์ชันนั้นได้และตั้งค่าจำนวนของร่องตัวแปร

func getRoom(roomId: String, onSuccess: @escaping(_ room: Room) -> Void) {
    DB.collection("Rooms").document(roomId).addSnapshotListener { document, error in
        DispatchQueue.main.async {
            if let dict = document?.data() {
                guard let decodeRoom = try? Room.init(fromDictionary: dict) else { return }
                onSuccess(decodeRoom)
            }
        }
    }
}

นี่ที่สองฟังก์ชันนั้นได้และตั้งค่าทั้งหมดตอบตัวแปร

func getNumParticipants(roomId: String, onSuccess: @escaping(_ numParticipants: Int) -> Void) {

    DB.collection("RoomsParticipants").document(roomId).collection("Participants").getDocuments { snapshot, error in
        DispatchQueue.main.async {
            if let error = error {
                print(error.localizedDescription)
                return
            } else {
                onSuccess(snapshot!.count)
            }
        }
    }
}

แล้วฉันใช้มันเมื่อฟังก์ชันเปรียบเทียบกับสองตัวแปรและโหลดมุมมอถ้าพวกเขาเท่าเทียมกันไม่เช่นนั้นก็แค่รอจนกว่าพวกเขาเท่าเทียม

func checkShowResults(roomId: String) {
    isLoading = true
    
    self.getNumParticipants(roomId: roomId) { numParticipants in
        print("Number of docs: \(numParticipants)")
        DispatchQueue.main.async {
            self.numParticipants = numParticipants
        }
    }
    
    self.getRoom(roomId: roomId) { room in
        print("Total answered: \(room.totalAnswered)")
        DispatchQueue.main.async {
            self.totalAnswered = room.totalAnswered
            if self.totalAnswered == self.numParticipants {
                self.showResults = true
            }
        }
    }
    
    isLoading = false
}

นี่คือผลของมุมมองที่ฉันกำลังพยายามแสดงผลพื้นฐานออกจาก fetched งข้อมูลออกมา

struct ResultsView: View {

@StateObject var resultsViewModel = ResultsViewModel()
var roomId: String

var body: some View {
    VStack {
        if !resultsViewModel.showResults {
                VStack {
                    ProgressView()
                    Text("Waiting for all participants \nto finish answering...")
                }
            } else {
                ShowResultsView()
                }
            }
        }
    }.navigationBarHidden(true)
    .onAppear {
        resultsViewModel.checkShowResults(roomId: roomId)
    }
}

แม้ว่า totalAnswered และ numParticipants เป็นเท่ากับตอนที่มุมมองในตอนแรกจะถูกแสดง,showResults คือเป็นคนจัดกันเรื่องจริงแล้ว แต่ตอนข้อมูลเปลี่ยนแปลงมันในที่สุดจะถูกตั้งค่าให้เป็นจริงถ้าพวกมันเท่ากับกลายเป็นอีกครั้ง ฉันคิดว่านี่เป็นเพราะรูปแบบ api โทรหาเพื่อ firebase/firestore คือกินเวลาและตัวแปรไม่ได้ตั้งค่ามาก่อนมุมมอบความสนใจ ฉันไม่รู้จริงๆว่าต้องการที่จะใช้ async/รอคำสั่ง.

1

คำตอบที่ดีที่สุด

2

ปัจจุบันของคุณรหัสประมวลผล self.getNumParticipants(..) เป็นอิสระแยกจาก self.getRoom(roomId: roomId). ยังไงก็ตาอยู่ checkShowResults, self.getRoom(roomId: roomId)ขึ้นอยู่กับ บ self.numParticipants ที่คุณเอามาจาก self.getNumParticipants(..). ดังนั้นคุณสามารถลองการซ้อนในของคุณฟังก์ชันโทรมา บางอย่างเหมือนตามรหัส:

func checkShowResults(roomId: String) {
    self.isLoading = true
    
    self.getNumParticipants(roomId: roomId) { numParticipants in
        print("Number of docs: \(numParticipants)")
        DispatchQueue.main.async {
            self.numParticipants = numParticipants
            
            // get the room after the numParticipants has been set
            self.getRoom(roomId: roomId) { room in
                print("Total answered: \(room.totalAnswered)")
                DispatchQueue.main.async {
                    self.totalAnswered = room.totalAnswered
                    if self.totalAnswered == self.numParticipants {
                        self.showResults = true
                        self.isLoading = false
                    }
                }
            }
            
        }
    }
2021-11-22 03:36:51

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่