我在加載視圖之前無法檢索 Firestore getdocument 資料。我知道它從多次檢查中回傳值,并且我處理異步函式的方式可能存在問題。
我試圖設定的三個變數。
@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
}
這是我試圖根據獲取的資料顯示的結果視圖。
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)
}
}
Even if the totalAnswered and numParticipants are equal when the view initially displayed, showResults is always set to false. But when the data changes it eventually gets set to true if they become equal again. I think this is because the API call to firebase/firestore is taking time and the variables aren't set before the view loads. I don't really want to use async/await.
uj5u.com熱心網友回復:
目前您的代碼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
}
}
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/370681.html
標籤:xcode asynchronous google-cloud-firestore swiftui async-await
上一篇:如何控制異步函式的流程?
下一篇:找到路徑認為是坐標平面
