AsyncKit
Utilities for asynchronous code inspired by JavaScript module 'async'.
Install / Use
/learn @mishimay/AsyncKitREADME
AsyncKit
Utilities for asynchronous code inspired by JavaScript module async.
AsyncKit is
- written in Swift
- generic
- less code
Quick Example
let async = AsyncKit<String, NSError>()
async.parallel(
[
{ done in done(.success("one")) },
{ done in done(.success("two")) }
]) { result in
print(result) // -> success(["one", "two"])
// the success array will equal ["one", "two"] even though
// the second closure had a shorter timeout.
}
async.series(
[
{ done in done(.success("one")) },
{ done in done(.success("two")) }
]) { result in
print(result) // -> success(["one", "two"])
}
var count = 0
async.whilst({ return count < 2 },
{ done in
count += 1
done(.success(String(count)))
}) { result in
print(result) // -> success(Optional("2"))
}
async.waterfall("one",
[
// argument is "one"
{ argument, done in done(.success("two")) },
// argument is "two"
{ argument, done in done(.success("three")) }
]) { result in
print(result) // -> success("three")
}
Usage
- Instantiate AsyncKit
-
You need to specify success object type and failure object type.
-
e.g.
let async = AsyncKit<String, NSError>()
- Prepare process closures
-
In the closure, call a passed closure with a success object or a failure object.
-
e.g.
let process: AsyncKit<String, NSError>.Process = { done in request() { object, error in if error == nil { done(.success(object)) } else { done(.failure(error)) } } }
- Pass the process closures to the AsyncKit function and receive a result
-
e.g.
async.parallel([process1, process2]) { result in switch result { case .success(let objects): print(objects) case .failure(let error): print(error) } }
parallel
func parallel(processes: [Process], completion: Result<[T], U> -> ())
Run the processes in parallel, without waiting until the previous process has completed. If any of the processes pass an error, the completion closure is immediately run with a failure result. Once the processes have completed successfully, the completion closure is run with a success result with an array of success objects.
Parameters
processes: An array containing closures whose type isAsyncKit<T, U>.Process. Each closure is passed a closure which it must execute with a success object or a failure object.completion: A closure to run once all the processes have succeeded or any process has failed. This closure gets a result containing either all the success objects or a failure object.
Example
AsyncKit<String, NSError>().parallel([
{ done in
if arc4random_uniform(4) == 0 {
done(.failure(NSError(domain: "AsyncKit", code: 0, userInfo: nil)))
} else {
done(.success("one"))
}
}, { done in
if arc4random_uniform(4) == 0 {
done(.failure(NSError(domain: "AsyncKit", code: 1, userInfo: nil)))
} else {
done(.success("two"))
}
}
]) { result in
switch result {
case .success(let objects):
print(objects) // -> success(["one", "two"])
// the success array will equal ["one", "two"] even though
// the second closure had a shorter timeout.
case .failure(let error):
print(error)
}
}
series
func series(processes: [Process], completion: Result<[T], U> -> ())
Run the processes in series, each one will run once the previous process has completed. If any processes in the series pass an error, no more processes are run, and the completion closure is immediately run with a failure result. Otherwise, the completion closure receives a success result with an array of success objects when processes have completed successfully.
Parameters
processes: An array containing closures whose type isAsyncKit<T, U>.Process. Each closure is passed a closure which it must execute with a success object or a failure object.completion: A closure to run once all the processes have succeeded or any process has failed. This closure gets a result containing either all the success objects or a failure object.
Example
AsyncKit<String, NSError>().series([
{ done in
if arc4random_uniform(4) == 0 {
done(.failure(NSError(domain: "AsyncKit", code: 0, userInfo: nil)))
} else {
done(.success("one"))
}
}, { done in
if arc4random_uniform(4) == 0 {
done(.failure(NSError(domain: "AsyncKit", code: 1, userInfo: nil)))
} else {
done(.success("two"))
}
}
]) { result in
switch result {
case .success(let objects):
print(objects) // -> success(["one", "two"])
case .failure(let error):
print(error)
}
}
whilst
func whilst(test: () -> Bool, _ process: Process, completion: Result<T?, U> -> ())
Repeatedly call process, while test returns true. Calls completion when stopped, or an error occurs.
Parameters
test: A test before each execution of process.process: A closure which is called each time test passes. The closure is passed a closure, which must be called once it has completed with a result.completion: A closure which is run after the test closure has failed and repeated execution of process has stopped. This closure gets a result containing either a optional success object passed to the final process's closure or a failure object.
Example
var count = 0
AsyncKit<String, NSError>().whilst({
return count < 2
},
{ done in
count += 1
if arc4random_uniform(4) == 0 {
done(.failure(NSError(domain: "AsyncKit", code: count, userInfo: nil)))
} else {
done(.success(String(count)))
}
}) { result in
switch result {
case .success(let object):
print(object) // -> Optional("2")
case .failure(let error):
print(error)
}
}
waterfall
func waterfall(argument: T, _ processes: [ProcessWithArgument], completion: Result<T, U> -> ())
Runs the tasks array of processes in series, each passing their result to the next. However, if any of the processes pass an error, the next process is not executed, and the completion closure is immediately run with the error.
Parameters
argument: A first argument.process: An array containing closures whose type isAsyncKit<T, U>.ProcessWithArgument. Each closure is passed a argument and a closure which it must call on completion with a success object or a failure object. The success object will be the next process's argument.completion: A closure to run once all the processes have succeeded or any process has failed. This closure gets a result containing either the final process's success object or a failure object.
Example
AsyncKit<String, NSError>().waterfall("one",
[
// argument is "one"
{ argument, done in
if arc4random_uniform(4) == 0 {
done(.failure(NSError(domain: "AsyncKit", code: 0, userInfo: nil)))
} else {
done(.success("two"))
}
},
// argument is "two"
{ argument, done in
if arc4random_uniform(4) == 0 {
done(.failure(NSError(domain: "AsyncKit", code: 1, userInfo: nil)))
} else {
done(.success("three"))
}
}
]) { result in
switch result {
case .success(let object):
print(object)
case .failure(let error):
print(error)
}
}
Requirements
Swift 3.0
Installation
CocoaPods
- AsyncKit is available through CocoaPods. To install it, simply add the following lines to your Podfile:
use_frameworks!
pod "AsyncKit"
- Run
pod install
Carthage
- Add the following to your Cartfile:
github "mishimay/AsyncKit"
- Run
carthage update - Add the framework as described. <br> See more Details: Carthage Readme
Author
Yuki Mishima, mishimaybe@gmail.com
License
AsyncKit is available under the MIT license. See the LICENSE file for more info.
Related Skills
node-connect
349.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
109.5kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
349.2kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
349.2kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
