Skip to content

Instantly share code, notes, and snippets.

@benhatsor
Last active August 31, 2025 18:37
Show Gist options
  • Select an option

  • Save benhatsor/d30a3c4d90088347982460e5aa7a71c6 to your computer and use it in GitHub Desktop.

Select an option

Save benhatsor/d30a3c4d90088347982460e5aa7a71c6 to your computer and use it in GitHub Desktop.
Escaped Continuation
///
/// # EscapedContinuation
///
/// ## Usage
///
/// 1. Call:
///
/// ```swift
/// let continuation = await EscapedContinuation<ReturnsType>()
/// ```
///
/// 2. Then, call either
/// ```swift
/// await continuation.onSuccess(_ value: ReturnsType)
/// await continuation.onError(_ error: any Error)
/// ```
/// somewhere else in your code (you can wrap it in a `Task` if neccessary).
/// > Note: The continuation must be resumed only once.
///
/// 3. Finally, return the result:
/// ```swift
/// return try await continuation.task.value
/// ```
///
actor EscapedContinuation<ReturnsType> {
var task: Task<ReturnsType, any Error>!
private var continuation: CheckedContinuation<ReturnsType, any Error>!
/// The continuation must be resumed exactly once.
private var didResume = false
func onSuccess(_ value: ReturnsType) {
guard !didResume else {
return
}
didResume = true
continuation.resume(returning: value)
}
func onError(_ error: any Error) {
guard !didResume else {
return
}
didResume = true
continuation.resume(throwing: error)
}
init() async {
task = Task {
return try await withCheckedThrowingContinuation { continuation in
self.continuation = continuation
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment