Yakka 是一个用于协调任务执行的工具包。以下是它的功能:
Yakka 可以用于您只需要在后台异步运行的临时代码,也可以用于协调复杂系统中的可重用组件。有很多不同的方法可以解决这类问题 – 希望这个方法适合您!
Yakka 涉及 3 个主要事物:
您可以使用闭包就地创建一个任务,或者您可以创建一个子类并在其中提供工作闭包。 这取决于您是否希望该工作在其他地方可重用。
如果您只想启动一个任务,也可以就地创建线路。 另外,它们也可以被保存并用于控制同时发生的事情的数量(这是它们的主要目的)。
如果您想将原本独立的任务组合成一个相关的组,以便您可以等待它们的组合完成,您可以使用 SerialTask 或 ParallelTask。 这些也只是 Task 的子类,因此您可以轻松创建它们,添加 onFinish 处理程序,并将它们发送到一条线路上。
GCD 在内部以下列方式使用:
在大多数情况下,您可以使用 Yakka 而无需关心 GCD。
let work = Task { process in
print("working...")
process.succeed()
}
Line().addTask(work).onFinish { outcome in
print("finished!")
}
请注意,同步和异步工作负载都受支持,只要您在完成时告诉进程对象即可。
let work = Task { process in
// do something here...
// a "process-aware task" would implement the following:
// if you can, report progress periodically like this:
process.progress(0.5) // percent 0..1
// or if you have to, provide progress via polling like this:
process.progress {
return someMethodWhichDeterminesPercentComplete()
}
// where it makes sense, check for cancellation and bail
if process.shouldCancel {
process.cancel()
return
}
// or if it's easier, respond to cancellation as needed
process.onShouldCancel {
process.cancel()
}
// finish up at some point with success or fail:
process.fail()
process.succeed()
}
work.onProgress { percent in
// update your UI etc
}
work.onStart {
// update your UI etc
}
work.onFinish { outcome in
// outcome is one of .successful, .failed, .cancelled)
}
Line().addTask(work)
var tasks = [Task]()
for ii in 0...4 {
let t = Task { (process) in
print(ii)
process.succeed()
}
tasks.append(t)
}
Line().addTask(ParallelTask(involving: tasks)).onFinish { (outcome) in
print("all tasks have finished")
}
var tasks = [Task]()
for ii in 0...4 {
let t = Task { (process) in
print(ii)
process.succeed()
}
tasks.append(t)
}
let group = SerialTask(involving: tasks)
Line().addTask(group).onFinish { (outcome) in
print("all tasks have finished")
}
class DigMassiveHole: Task {
let diameter: Float
let depth: Float
var numEmployees = 1
init(diameter: Float, depth: Float) {
// Some config
self.diameter = diameter
self.depth = depth
super.init()
// Define what this task does
workToDo { (process) in
print("doing some digging...")
process.succeed()
}
}
}
let dig = DigMassiveHole(diameter: 30, depth: 100)
dig.numEmployees = 5
Line().addTask(dig).onFinish { (outcome) in
print("finished digging!")
}
// Create a line which we'll keep around
let uploadLine = Line(maxConcurrentTasks: 5)
// Receive events of interest
uploadLine.onBecameEmpty {
print("upload line isn't busy")
}
uploadLine.onNextTaskStarted { task in
print("upload line started another task")
}
// Create some upload tasks
let first = Task { (process) in
print("first upload")
process.fail()
}
let second = Task { (process) in
print("second upload")
process.succeed()
}
let third = Task { (process) in
print("third upload")
process.succeed()
}
// Run a task now
uploadLine.addTask(first)
// Later... run some more!
uploadLine.addTasks([second, third])
uploadLine.add { () -> Task in
return someMethodWhichCreatesATask()
}
// Anytime later...
uploadLine.stop() // or
uploadLine.stopAndCancel()
let someProcess = task1 --> task2 --> task3 // serial
let anotherProcess = taskA --> taskB --> taskC // serial
let overall = someProcess ||| anotherProcess // parallel
overall.onFinish { outcome in
print("all tasks finished")
}
Line().addTask(overall)
这些示例都在工作闭包结束时完成工作(它们是同步的),但是您可以查看测试文件以获取更多示例,其中工作在任意稍后的时间完成。
关于此的一些要点:
任务在运行时保留自身,这样做是有意为之,目的是使它们更易于使用。 任务使用的工作队列也在运行时保留。 您要做的就是确保您的工作最终通过调用进程对象上的方法之一来完成,并且该进程对象不会在该点之后被强引用。
SerialTask 和 ParallelTask 都会保留您提供给它们的任务,无论它们是否已启动。 它们在运行时保留自身,因为它们也只是 Tasks。
线路不会保留自身,并且在临时情况下,它们将在超出范围时被释放,但是任务继续运行不需要它们。
onStart 和 onFinish 上的事件闭包可以保留任务,因为它们将在这些事件发生后被释放。 但是,onProgress 和 onRetry 闭包在任务的生命周期内被保留,因此您不希望在这些事件闭包中强捕获任务。
就像 Hard Yakka – 澳大利亚俚语中“努力工作”的意思。 它源自“yaga”,这是布里斯班地区原住民使用的 Yagara 语言中的一个术语。
Yakka 可通过 CocoaPods 获得。 要安装它,只需将以下行添加到您的 Podfile 中
pod "Yakka"
可以使用 Carthage 安装 Yakka。 将以下内容添加到您的 Cartfile 中
github "KieranHarper/Yakka" ~> 2.0
也支持通过 Swift Package Manager 安装。 将以下内容添加到您的 Package 文件中
dependencies: [
.Package(url: "https://github.com/KieranHarper/Yakka.git", majorVersion: 2)
]
只需从 Sources 目录中拖动文件即可!
Kieran Harper, kieranjharper@gmail.com, @KieranTheTwit
Yakka 在 MIT 许可证下可用。 有关更多信息,请参见 LICENSE 文件。