swift - 有没有办法使用作为参数传递的完成处理程序来检测长请求何时完成
问题描述
在将函数作为参数传递时,我无法理解如何使用闭包来处理已完成的事件。
这是一个非常人为的例子:
class MessageService {
func sendMessage(s: String) {
print(s)
}
var messenger: Messenger {
createMessenger(completion: sendMessage(s:))
}
}
func createMessenger(completion: @escaping (String) -> Void) -> Messenger {
return Messenger { completion("This is a hardcoded message.") }
}
struct Messenger {
let sendMessage: () -> Void
init(sendMessage: @escaping () -> Void) {
self.sendMessage = sendMessage
}
}
let service = MessageService()
let messenger = service.messenger
messenger.sendMessage()
我想知道什么时候sendMessage
完成(例如,如果它正在执行类似网络请求的操作),那么有没有办法拥有一个完成处理程序,sendMessage
以便我可以写一些类似的东西:
messenger.sendMessage {
print("I finished sending a message!")
}
我尝试在服务类中添加这样的完成处理程序:
func sendMessage(s: String, completion: @escaping () -> Void) {
MessageRequest(with: s) {
completion()
}
}
但是当我尝试使用该createMessenger
方法时,事情开始变得非常混乱,因为上面的函数有一些(String, () -> ()) -> ()
我不知道如何处理的疯狂类型。任何帮助将不胜感激,谢谢。
解决方案
所以,听起来你想要的是一个任意的 Messenger 类型,它的创建者告诉它要做什么动作,一旦动作完成,它就会调用它的调用者的完成处理程序。
如果您使用typealias
描述性名称来跟踪所有闭包,它会有所帮助。如果您不介意,我将其更笼统地命名为Agent
:
struct Agent {
typealias Completion = () -> Void
typealias Action = (Completion) -> Void
private let action: Action
static func create(action: @escaping Action) -> Agent {
Agent(action: action)
}
func execute(_ completion: @escaping Completion) {
action(completion)
}
}
因此,Agent
可以使用接受完成处理程序以在完成时发出信号的任意操作来创建:
let agent = Agent.create { completion in
print("started executing action")
DispatchQueue.main.asyncAfter(deadline: .now() + 2) { completion() }
}
agent.execute { print("done") }
现在,您可以将其调整到您的MessengerService
班级:
class MessageService {
func sendMessage(s: String) {
print(s)
}
var messenger: Agent {
Agent.create { completion in
sendMessage("This is a hardcoded message.")
completion()
}
}
}
推荐阅读
- javascript - 有没有其他方法可以在我们的 Angular Web 应用程序中加载外部网站的内容?
- javascript - 使用前置摄像头扫描二维码 react native
- python - 我的变量如何自相矛盾地既是 ndarray 又是 dict?
- java - 关于如何实例化类的问题(Javadoc 不清楚)
- lua - luasec 在 5.1 和 5.2 中失败,但在 5.3 中正常
- android - 如何更改 viewpager 中每个片段的点指示器(活动和非活动)的颜色?
- c - 将 C while 循环转换为 Pascal
- python - Google Dataflow 和 Apache Beam:为什么选择 ValueProvider
- c++ - 在添加 VEH 之前放置页面保护时出现“未实现”错误
- python - 在python中使用beautifulsoup提取表数据时出现问题