Swift Async Algorithms open-source package
set of algorithms specifically focused on processing values over time using
AsyncSequenceincorporates more advanced algorithms, as well as interoperating with clocks
AsyncSequence
protocol that lets you describe values produced asynchronously
just like
Sequencebut uses Swift concurrency (next()function from its iterator,AsyncIterator, isasync)
Multi-input algorithms
algorithms that take multiple input
AsyncSequencesand produce one outputAsyncSequencefocused on combining
AsyncSequencestogether in different ways
Examples:
zip(_:...)- creates an asynchronous sequence of pairs built out of underlying asynchronous sequences
for try await (vid, preview) in zip(videos, previews) {
try await upload(vid, preview)
}merge(_:...)- merges two or more asynchronous sequence into a single asynchronous sequence producing the elements of all of the underlying asynchronous sequences (elements types must be the same)
for try await message in merge(primaryAccount.messages, secondaryAccount.messages) {
displayPreview(message)
}Clock, Instant, and Duration
new API in Swift 5.7
Clock
Swift protocol, defines:
a way to wake up after a given instant
a way to produce a concept of “now”
Two built-in Clocks definitions are ContinuousClock and the SuspendingClock:
use
ContinuousClockto measure time just like a stopwatch, where time progresses no matter the state of the thing being measuredSuspendingClock, on the other hand, suspends when the machine is put to sleep
// Sleep until a given deadline
let clock = SuspendingClock()
var deadline = clock.now + .seconds(3)
try await clock.sleep(until: deadline) The key difference between these two clocks is that the ContinuousClock progresses while/when/if the machine is asleep.
Use SuspendingClock for:
Measuring device time
Delays for animation
Use ContinuousClock for:
Measuring human time
Delays by an absolute duration
Swift Async Algorithms
the package brings in a family of algorithms to work with time by leveraging these new Swift APIs
Examples:
let queries = searchValues.debounce(for: .milliseconds(300))
for await query in queries {
let results = try await performSearch(query)
await channel.send(results)
}chunks(...)andchunked(...)- groups elements into collections by count/time/content
let batches = outboundMessages.chunked(
by: .repeating(every: .milliseconds(500))
)
let encoder = JSONEncoder()
for await batch in batches {
let data = try encoder.encode(batch)
try await postToServer(data)
}Collections
the package offers a set of initializers for constructing collections using
AsyncSequence(array, set, dictionary)
