合并:将 Closure 转换为 Publisher
Posted
技术标签:
【中文标题】合并:将 Closure 转换为 Publisher【英文标题】:Combine: Convert Closure into Publisher 【发布时间】:2020-05-17 03:23:08 【问题描述】:如何转换:
func getResults(completion: ([Result]?, Error) -> Void)
进入
var resultsPublisher: AnyPublisher<[Result], Error>
只是我看到的一个方案(这种语法不存在):
var resultsPublisher: AnyPublisher<[Result], Error>
let publisher: AnyPublisher = ... // init
getResults results, error in
guard let results = results else
publisher.produce(error: error) // this syntax doesn't exist
return
publisher.produce(results: results) // this syntax doesn't exist
return publisher
我需要它,因为一些 3d 方 SDK 使用 completion closures
,我想为它们编写扩展以返回 Publishers
。
【问题讨论】:
只需将其包装在 Future 中即可。我只是花了一天时间做这件事!见apeth.com/UnderstandingCombine/publishers/publishersfuture.html 谢谢!你能发布你的答案吗?我会把它标记为正确的,所以它会在未来帮助任何人???? 你没有给我足够的信息让我写一个实际的代码答案,这件事非常初级和明显。但你可以回答你自己的问题! 【参考方案1】:答案是Future
Publisher as matt
解释:
var resultsPublisher: AnyPublisher<[Result], Error>
// need deferred when want
// to start request only when somebody subscribes
// + without Deferred it's impossible to .retry() later
Deferred
Future promise in
self.getResults results, error in
guard let results = results else
promise(.failure(error))
return
promise(.success(results))
.eraseToAnyPublisher()
【讨论】:
一个想法:在getResults
的第一行放置一个断点,并确保它仅在您期望的时候被调用。有时 Future 需要被包裹在 Deferred 中,我不知道这是否是其中一种情况。
谢谢。似乎 Future 在创建后立即启动,即使没有订阅它,所以对我来说最好使用 Defered + 它允许 .retry() 以防出现错误
很好,很高兴我们发现了这一点。以上是关于合并:将 Closure 转换为 Publisher的主要内容,如果未能解决你的问题,请参考以下文章
Swift 解析 JSON 时出现问题:无法将“__NSCFDictionary”类型的值转换为“NSArray”错误
如何有效地将 google-closure javascript 转换为现代 ES6?