Multiple LongLiving Effects #1313
-
What is the best to handle two or more unrelated long-living effects that are kicked-off from the same action (.task modifier). For example return .run { send in
for try await typeA in aAsyncSequence {
await send(.typeAResult(typeA))
}
for try await typeB in bAsyncSequence {
await send(.typeBResult(typeB))
}
} In this case, only the first sequence will send any events, presumably because it never completes. In my current solution, I map both async sequences to a common type, use the merge operator, and then switch over the value. enum CommonResultType {
case typeA(TypeA)
case typeB(TypeB)
}
return .run { send in
for try await commonType in merge(
aAsyncSequence.map { CommonResultType.typeA($0) },
bAsyncSequence.map { CommonResultType.typeB($0) }) {
switch commonType {
case .typeA(let typeA):
send(.typeAResult(typeA))
case .typeB(let typeB):
send(.typeBResult(typeB))
}
} Although this works, I am sure I'm missing a cleaner/simpler solution. Is there a better way to do this? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Hey @corysullivan, since the return .run { send in
await withTaskGroup(Void.self) { group in
group.addTask {
for try await typeA in aAsyncSequence {
await send(.typeAResult(typeA))
}
}
group.addTask {
for try await typeB in bAsyncSequence {
await send(.typeBResult(typeB))
}
}
}
} |
Beta Was this translation helpful? Give feedback.
Hey @corysullivan, since the
.run
closure is provided an async context you can use any and all of Swift's concurrency tools in there. For example, task groups are one way to start up two parallel tasks: