swift - 未正确等待来自 Firebase 的 Swift 查询
问题描述
我正在尝试从 Firebase 查询文档,但我无法正确等待函数的响应。我已经尝试过 Future,但似乎我无法从查询正文中返回承诺。您能帮我吗,如何正确查询然后使用 Swift (Combine) 和 Firebase 订阅它?
我需要知道查询的结果(错误/空/成功),如果成功,则使用查询的值。这可能吗?
查询:
func getProductByCode(code: String) -> Future<[Product], QueryError> {
return Future { promise in
self.db.collection("products")
.whereField("code", isEqualTo: code)
.getDocuments { (querySnapshot, error) in
if let error = error {
print("Error on loading products: \(error.localizedDescription)")
return promise(.failure(.error))
}
if let querySnapshot = querySnapshot {
if querySnapshot.isEmpty {
print("Empty products list")
return promise(.failure(.empty))
} else {
self.products = querySnapshot.documents.compactMap { document in
try? document.data(as: Product.self)
}
print("List of products: \(self.products)")
return promise(.success(self.products))
}
}
}
}
}
enum QueryError: Error {
case empty
case error
}
方法调用,订阅:
productRepository.getProductByCode(code: qrText)
.sink(receiveCompletion: { completion in
switch completion {
case .failure(.error):
print("ERROR on retrieving products")
case .failure(.empty):
print("EMPTY products")
default:
print("ALRIGHT")
}
}, receiveValue: { value in
print("Returned value: \(value)")
// Here I should get the result of the query and then use it.
})
//After the method call I would like to use the result value.
//But I cannot correctly await it.
//It would be called before the async function returns the value.
我对任何形式的改变持开放态度,我尝试过 Future,因为它可以返回承诺,我们可以订阅它。如果有更好的解决这种情况的方法,请帮忙。
解决方案
如果我理解正确。问题的症结在于网络请求的异步性。
productRepository.getProductByCode(code: qrText)
.sink(receiveCompletion: { completion in
switch completion {
case .failure(.error):
print("ERROR on retrieving products")
case .failure(.empty):
print("EMPTY products")
default:
print("ALRIGHT")
}
}, receiveValue: { value in
print("Returned value: \(value)")
// Here I should get the result of the query and then use it.
})
// You want to use the value here? For example:
self.label.text = value
您是否可以使用函数来完成您想要使用该值的目的,或者将使用该值的代码放在receiveValue
块中?例如:
productRepository.getProductByCode(code: qrText)
.sink(receiveCompletion: { completion in
switch completion {
case .failure(.error):
print("ERROR on retrieving products")
case .failure(.empty):
print("EMPTY products")
default:
print("ALRIGHT")
}
}, receiveValue: { value in
print("Returned value: \(value)")
updateLabel(value: value) // <- Function won't be called until this block fires and we have the `value`
})
func updateLabel(value: String) {
self.label.text = value
}
推荐阅读
- angular - NG0100:ExpressionChangedAfterItHasBeenCheckedError:表达式在检查后已更改
- typescript - 从用户获取任何类型的用户文本
- python - 在Django中计算两个指定天之间的天数?
- spring-integration - 存在时替换文件在 Spring Integration Smb 中不起作用
- php - 使用 Php 用一个锚标签替换两个/三个单词
- transactions - 托管支付页面交易返回“错误:302”
- javascript - CK Editor(经典编辑器)从父组件更新数据
- mysql - SQLAlchemy ORM 查询加入聚合子查询
- r - 如何通过将条形图位置映射到原始图的比例,将条形图覆盖在具有不同几何形状的其他图之上
- javascript - 使用手风琴表格形式解析 php 中的嵌套 json 数据