withTaskCancellation(id:cancelInFlight:isolation:operation:)
Execute an operation with a cancellation identifier.
func withTaskCancellation<T>(id: some Hashable & Sendable, cancelInFlight: Bool = false, isolation: isolated (any Actor)? = #isolation, operation: @escaping () async throws -> T) async rethrows -> T where T : Sendable
Parameters
- id
A unique identifier for the operation.
- cancelInFlight
Determines if any in-flight operation with the same identifier should be canceled before starting this new one.
- isolation
The isolation of the operation.
- operation
An async operation.
Returns
A value produced by operation.
Throws
An error thrown by the operation.
If the operation is in-flight when Task.cancel(id:)
is called with the same identifier, the operation will be cancelled.
enum CancelID { case timer }
await withTaskCancellation(id: CancelID.timer) {
// Start cancellable timer...
}
Debouncing tasks
When paired with a clock, this function can be used to debounce a unit of async work by specifying the cancelInFlight
, which will automatically cancel any in-flight work with the same identifier:
@Dependency(\.continuousClock) var clock
enum CancelID { case response }
// ...
return .run { send in
try await withTaskCancellation(id: CancelID.response, cancelInFlight: true) {
try await self.clock.sleep(for: .seconds(0.3))
await send(
.debouncedResponse(TaskResult { try await environment.request() })
)
}
}