[英]How to make a method execute methods synchronously
我嘗試使用 DispatchQueue 和 DispatchGroup 但它仍然是異步的,我也嘗試了 dispatchQueue.Async 和 dispathQueue.sync 都沒有工作。
myFunc 是在 init() 中調用的 function,它本身調用 2 個函數,getArrOneData() 和 getArrTwoData([ArrOneType])。
第一個 function 從 firestore 下載 ArrOneType 數據並返回一個初始化為字段的數組。
第二個 function 使用從第一個 function 下載的數據/字段來初始化 ArrTwoType 中的字段,同時從 firestore 下載其他相關的 ArrTwoType 數據以作為數組返回。
所以問題是它仍然是異步的。 在這種情況下如何正確使用 DispatchQueue 和 DispatchGroup?
謝謝
注意:獲取 arrTwoData 主要是偽代碼
func myFunc(){
let group = DispatchGroup()
let dispatchQueue = DispatchQueue.global(qos: .default)
group.enter()
dispatchQueue.sync {
self.arrOne = self.getArrOneData()//getArrOneData gets data from firestore
group.leave()
}
dispatchQueue.sync {
group.enter()
self.arrTwo = self.getArrTwoData(inputArr: self.arrOne)//getArrTwoData gets data from firestore
group.leave()
}
}
//ArrOneType is an array field in ArrTwoType
func getArrTwoData(inputArr: [ArrOneType]) -> [ArrTwoType]{
var result = [ArrTwoType]()
//retrieving data from firestore, code excluded...
for document in querySnapshot!.documents {
let data = document.data()
name = data["Name"] as? String ?? "Name Unknown"
//returns an array which is a subset of inputArr filtered by name, however
//I dont think the inputArr is populated at this point when I run the program
var field2:[ArrOneType] = someFunc(name, inputArr)
var x = ArrTwoType(name: name, field2: field2)
result.append(x)
}
}
}
return result
}
如果您有兩個請求,一個使用來自一個的響應來准備下一個請求,則想法是對所有異步方法使用@escaping
完成處理程序閉包,例如
func getArrayOneData(completion: @escaping (Result<[ArrayOneType], Error>) -> Void) {
someAsynchronousMethod {
let values: [ArrayOneType] = ...
completion(.success(values))
}
}
func getArrayTwoData(for typeOneValues: [ArrayOneType], completion: @escaping (Result<[ArrayTwoType], Error>) -> Void) {
someAsynchronousMethod(for: typeOneValues) {
let values: [ArrayTwoType] = ...
completion(.success(values))
}
}
然后您可以執行以下操作:
func getEverything(completion: @escaping (Result<[ArrayTwoType], Error>) -> Void) {
getArrayOneData { result in
switch result {
case .failure(let error):
print(error)
case .success(let typeOneValues):
getArrayTwoData(for: typeOneValues) { result in
switch result {
case .failure(let error):
print(error)
case .success(let typeTwoValues):
completion(.success(typeTwoValues))
}
}
}
}
}
請注意,不需要調度組。 將完成處理程序添加到異步方法后,我們可以從第一個完成處理程序中調用第二個方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.