54 lines
1.2 KiB
Swift
54 lines
1.2 KiB
Swift
//
|
|
// AsyncPromise.swift
|
|
// punchnet
|
|
//
|
|
// Created by 安礼成 on 2026/5/27.
|
|
//
|
|
import Foundation
|
|
|
|
public actor AsyncPromise<Value: Sendable> {
|
|
private enum State {
|
|
case pending([CheckedContinuation<Value, Error>])
|
|
case completed(Result<Value, Error>)
|
|
}
|
|
|
|
private var state: State = .pending([])
|
|
|
|
public init() {
|
|
|
|
}
|
|
|
|
public func value() async throws -> Value {
|
|
try await withCheckedThrowingContinuation { continuation in
|
|
switch state {
|
|
case .pending(var continuations):
|
|
continuations.append(continuation)
|
|
state = .pending(continuations)
|
|
|
|
case .completed(let result):
|
|
continuation.resume(with: result)
|
|
}
|
|
}
|
|
}
|
|
|
|
public func succeed(_ value: Value) {
|
|
complete(.success(value))
|
|
}
|
|
|
|
public func fail(_ error: Error) {
|
|
complete(.failure(error))
|
|
}
|
|
|
|
private func complete(_ result: Result<Value, Error>) {
|
|
guard case .pending(let continuations) = state else {
|
|
return
|
|
}
|
|
|
|
state = .completed(result)
|
|
|
|
for continuation in continuations {
|
|
continuation.resume(with: result)
|
|
}
|
|
}
|
|
}
|