From 316ae959966af45e262854dedb1f8c7023384d48 Mon Sep 17 00:00:00 2001 From: mlch911 Date: Mon, 27 Mar 2023 17:42:45 +0800 Subject: [PATCH 1/2] Add Support for Swift Async/Await --- Sources/Promises/Promise+Async.swift | 48 ++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Sources/Promises/Promise+Async.swift b/Sources/Promises/Promise+Async.swift index 45db623..58bb952 100644 --- a/Sources/Promises/Promise+Async.swift +++ b/Sources/Promises/Promise+Async.swift @@ -40,3 +40,51 @@ public extension Promise { objCPromise.__addPendingObject(self) } } + +#if swift(>=5.5) +#if canImport(_Concurrency) +@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +public extension Promise { + func async() async throws -> Value { + try await withCheckedThrowingContinuation { continuation in + then { value in + continuation.resume(returning: value) + }.catch { error in + continuation.resume(throwing: error) + } + } + } +} + +@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) +public extension Promise { + typealias SwiftAsync = (@escaping (Value) -> Void, @escaping (Error) -> Void) async throws -> Void + + /// Creates a pending promise and executes `work` block asynchronously on the given `queue`. + /// - parameters: + /// - queue: A queue to invoke the `work` block on. + /// - work: A block to perform any operations needed to resolve the promise. + convenience init(on queue: DispatchQueue = .promises, _ work: @escaping SwiftAsync) { + let objCPromise = ObjCPromise.__onQueue(queue) { fulfill, reject in + Task { + do { + try await work({ value in + if type(of: value) is NSError.Type { + reject(value as! NSError) + } else { + fulfill(Promise.asAnyObject(value)) + } + }, reject) + } catch let error { + reject(error as NSError) + } + } + } + self.init(objCPromise) + // Keep Swift wrapper alive for chained promise until `ObjCPromise` counterpart is resolved. + objCPromise.__addPendingObject(self) + } +} + +#endif +#endif From 1c0a445db42fbba1bc2b509907a1bb5756d8f2ea Mon Sep 17 00:00:00 2001 From: mlch911 Date: Tue, 16 May 2023 19:13:42 +0800 Subject: [PATCH 2/2] Update Promise+Async --- Sources/Promises/Promise+Async.swift | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Sources/Promises/Promise+Async.swift b/Sources/Promises/Promise+Async.swift index 58bb952..517c9f6 100644 --- a/Sources/Promises/Promise+Async.swift +++ b/Sources/Promises/Promise+Async.swift @@ -56,6 +56,14 @@ public extension Promise { } } +public extension Task { + func asPromise() -> Promise { + Promise { fulfill, reject in + fulfill(try await self.value) + } + } +} + @available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *) public extension Promise { typealias SwiftAsync = (@escaping (Value) -> Void, @escaping (Error) -> Void) async throws -> Void