【发布时间】:2021-06-19 13:12:43
【问题描述】:
我知道有几个问题具有类似的结构,但我真的很苦恼如何让我的代码调用检索 Firestore 数据的方法,等到异步函数完成后再返回。
目前我有调用getPledgesInProgress 的父函数,该方法从firebase 检索数据。该方法在父节点初始化时调用。
@State var pledgesInProgress = [Pledge]()
var pledgePicked: Pledge?
var body: some View {
VStack{
//LOTS OF CODE HERE WHICH ISN'T RELEVANT
}
func initVars(){
pledgesInProgress = getPledgesInProgress(pledgePicked: pledgePicked ?? emptyPledge)
}
}
问题在于,progresssInProgress 变量被初始化为一个空数组,因为父级不会等到被调用函数完成获取 Firestore 文档后再继续。
func getPledgesInProgress(pledgePicked: Pledge)-> [Pledge]{
let db = Firestore.firestore()
var pledgesToReturn = [Pledge]() //INITIALISED AS EMPTY
db.collection("Pledges")
.getDocuments { (snapshot, error) in
guard let snapshot = snapshot, error == nil else {
//handle error
return
}
snapshot.documents.forEach({ (documentSnapshot) in
let documentData = documentSnapshot.data()
pledgesToReturn.append(findPledgeWithThisID(ID: documentData["ID"] as! Int))
})
}
//PROBLEM!!!! returned before getDocuments() completed
return pledgedToReturn
}
问题是在 getDocuments() 方法完成之前返回了数组 promisesToReturn,所以每次都返回一个空数组。请有人能帮我理解如何让方法等到这个调用完成吗?谢谢
N.B Pledge 是一种自定义数据类型但没关系,它是关于了解如何等待异步功能完成。您可以将 Pledge 数据类型替换为您喜欢的任何数据类型,它仍然是相同的原则
【问题讨论】:
-
您不想“等待”,除非您使用的是 iOS 15 的新
async await。您应该将pledgesToReturn放在@Published之外,以便在完成后更新并刷新View -
@loremipsum 是我想要发布的
pledgesInProgress数组吗?这是我在调用函数中分配返回值的那个,并将在代码中进一步使用? -
不会,因为您将直接引用正在填充的变量。您还没有显示所有代码,但我假设您的方法在 ViewModel 中只需引用 ViewModel 中的变量
-
你可以随心所欲地调用它,名字并不重要,关键是你的方法应该更新一个 SwiftUI 包装器变量,以便视图可以获取更新
标签: swift asynchronous google-cloud-firestore swiftui