Slide 49
Slide 49 text
class Future {
private enum Result { case error(Error), value(T) }
private var result: Result? = nil
private var awaiters: [(Result) -> Void] = []
// Fulfill the future, and resume any coroutines waiting for the value.
func fulfill(_ value: T) {
precondition(self.result == nil, "can only be fulfilled once")
let result = .value(value)
self.result = result
for awaiter in awaiters {
awaiter(result)
}
awaiters = []
}
// Mark the future as having failed to produce a result.
func fail(_ error: Error) {
precondition(self.result == nil, "can only be fulfilled once")
let result = .error(error)
self.result = result
for awaiter in awaiters {
awaiter(result)
}
awaiters = []
}
func get() async throws -> T {
switch result {
// Throw/return the result immediately if available.
case .error(let e)?:
throw e
case .value(let v)?:
return v
// Wait for the future if no result has been fulfilled.
case nil:
return await suspendAsync { continuation, error in
awaiters.append({
switch $0 {
case .error(let e): error(e)
case .value(let v): continuation(v)
}
})
}
}
}
// Create an unfulfilled future.
init() {}
convenience init(_ body: () async -> T) {
self.init()
beginAsync {
do {
self.fulfill(await body())
} catch {
self.fail(error)
}
}
}
}
class Future
w ϓϩϙʔβϧʹΫϦε͞Μͷ࣮ྫ
w ଞͷݴޠͰ1SPNJTF5BTL%FGFSSFE͕͋Δ