我有一个协议定义如下:
protocol Prompter {
func promptIfNeeded() async -> Bool
}
以及一组
Prompter
一致类型:
var prompters: [Prompter] { [PrompterA(), PrompterB()] }
目前,我迭代这个数组,使用
async
await
: 一条一条地向用户提示每条消息
for prompter in prompters {
let result = await prompter.promptIfNeeded()
print("The result is \(result)")
}
但是,我很好奇利用
Combine
出版商而不是 async
await
。有这方面的指导吗?
注意 - 每个提示必须等待前一个提示完成
Publishers.Sequence
和 flatMap
以及 Subscribers.Demand
的 .max(1)
。显然,该方法需要返回一个 Future
。所以,也许:
protocol Prompter {
func prompt() -> Future<Bool, Never>
}
struct PrompterA: Prompter {
func prompt() -> Future<Bool, Never> {
Future { promise in
…
promise(.success(result)) // where `result` is some `Bool`
}
}
}
struct PrompterB: Prompter { … }
class Foo {
var cancellables: Set<AnyCancellable> = []
func performPrompts() {
let prompts: [Prompter] = [PrompterA(), PrompterB()]
Publishers.Sequence(sequence: prompts)
.flatMap(maxPublishers: .max(1)) { $0.prompt() }
.sink { print($0) }
.store(in: &cancellables)
}
}
主题还有其他变体,但希望这能说明这个想法。将
flatMap
与 maxPublishers
的 .max(1))
结合使用可能会实现您对合并的需求。