在分派异步中包装完成处理程序的语法

Syntax to wrap a completion handler in dispatch async

我有一个完成处理程序需要分配给 属性,但我希望它异步执行。

如果我没有那个要求,我会写:

request.completionBlock = completionBlock

但是因为我有这个需求,所以我不得不写这个

request.completionBlock = { response, error in
  DispatchQueue.main.async {
    completionBlock(response, error)
  }
}

这似乎是多余的和不敏捷的。

有没有更简单的语法?我想写类似

request.completionBlock = completionBlock.map(DispatchQueue.main.async)

我能用这么简单的方式表达我的需求吗?

没有用于表达它的内置语法,但您始终可以定义一个通用函数或运算符来启用这些内容。

例如:

infix operator >

func ><T>(left:@escaping (T)->(), right:DispatchQueue) -> (T)->() {
  return { input in
    right.async { left(input) }
  }
}

定义了上述自定义运算符后,您的代码可以是:

request.completionBlock = completionBlock > DispatchQueue.main

我认为这是您正在寻找的一般感觉。

您可以控制 request class 吗?如果没有,那么我认为你必须硬着头皮自己显式异步调度(显式是好的,或者至少它在 python :-) ),或者像 Daniel 一样定义你自己的 shorthand霍尔建议。

如果您确实有控制权,那么我认为值得建议的是简单地更改 request class 的 API 以确保在主线程上调用完成处理程序.毕竟,完成处理程序应该很快,而且这通常是您想要的。

这是一个扩展

extension DispatchQueue {
    func asyncClosure<T>(_ closure:@escaping (T) -> Void) -> (T) -> Void {
        return {i in self.async {closure(i)}}
    }
}

允许您这样做:

request.completionBlock = DispatchQueue.main.asyncClosure(completionBlock)