Open churabou opened 6 years ago
enum State { case pending case resolve case reject } enum Result<T> { case undefined case value(T) case error(Swift.Error) } public final class Promise<T> { private(set) var state: State = .pending { didSet { if case .pending = oldValue { switch (state, result) { case (.resolve, .value(let value)): resolve?(value) case (.reject, .error(let error)): reject?(error) default: break } } } } private var resolve: ((T) -> Void)? private var reject: ((Swift.Error) -> Void)? internal private(set) var result: Result<T> = .undefined public init(_ executor: @escaping ((T) -> Swift.Void, (Swift.Error) -> Swift.Void) -> Swift.Void) { DispatchQueue.main.async { executor(self.resolved, self.rejected) } } // stateとresultを更新する private func resolved(value: T) { if case .pending = state { result = .value(value) state = .resolve } } // stateとresultを更新する private func rejected(error: Swift.Error) { if case .pending = state { result = .error(error) state = .reject } } } enum State { case pending case fulfilled case rejected case resolved } enum Result<T> { case undefined case value(T) case error(Error) } class Promise<T> { private (set) var state: State = .pending { didSet { // then if case .pending = oldValue { switch (state, result) { case (.fulfilled, .value(let value)): resolve?(value) case (.rejected, .error(let error)): reject?(error) default: break } } } } private var resolve: FullfillClosure? private var reject: RejectClosure? func then<U>(onFulfilled: @escaping (T) -> U, _ onRejected: ((Error) -> Void)?) -> Promise<U> { return Promise<U> { resolve, _reject in switch (self.state, self.result) { case (.pending, _): self.resolve = { (value: T) in _resolve(onFulfilled(value)) } // let resolve = self.resolve // self.resolve = { // resolve?($0) // _resolve(onFulfilled($0)) // } default: break } } } private var result: Result<T> = .undefined typealias FullfillClosure = (T) -> Swift.Void typealias RejectClosure = (Error) -> Swift.Void public init(_ executor: @escaping (FullfillClosure, RejectClosure) -> Swift.Void) { DispatchQueue.main.async { executor(self.onFullfilled, self.onRejected) } } func onFullfilled(value: T) { if case .fulfilled = state { result = .value(value) state = .fulfilled } } private func onRejected(error: Error) { if case .pending = state { result = .error(error) state = .rejected } } } let taskA = Promise<Int> { fullfill , error in }