swift - 如何使方法同步执行方法
问题描述
我尝试使用 DispatchQueue 和 DispatchGroup 但它仍然是异步的,我也尝试了 dispatchQueue.Async 和 dispathQueue.sync 都没有工作。
myFunc 是在 init() 中调用的函数,它本身调用 2 个函数,getArrOneData() 和 getArrTwoData([ArrOneType])。
第一个函数从 firestore 下载 ArrOneType 数据并返回一个初始化为字段的数组。
第二个函数使用从第一个函数下载的数据/字段来初始化 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))
}
}
}
}
}
请注意,不需要调度组。将完成处理程序添加到异步方法后,我们可以从第一个完成处理程序中调用第二个方法。
推荐阅读
- angular - 如何将项目从 Angular 9 应用程序拖放到 iframe
- python - python中forloop中的名称未定义错误
- sql - EF Core 为每个新迁移创建重复的更改
- python-3.x - 在 Python 中使用 Swagger 和 Connexion 获取 utf-8 而不是 \u 转义序列
- swift - SwiftUI .onDelete 从 ForEach 获取 var
- selenium - 如何通过多个文本匹配单击一个元素?
- python - 无法从 azure.storage.blob 导入名称 BlockBlobService
- c++ - 无法将 'wchar_t*' 转换为 'LPCSTR' {aka 'const char*'}
- android - Paging3:在 Room DAO 中使用 PagingSource 作为返回类型时,“不确定如何将游标转换为此方法的返回类型”
- java - JPanel的平滑圆角