diff --git a/Sources/AnyPromise.h b/Sources/AnyPromise.h index fd1ad3a9b..cf0d76b45 100644 --- a/Sources/AnyPromise.h +++ b/Sources/AnyPromise.h @@ -182,6 +182,13 @@ typedef void (^PMKResolver)(id __nullable) NS_REFINED_FOR_SWIFT; */ - (AnyPromise * __nonnull(^ __nonnull)(dispatch_queue_t __nonnull, dispatch_block_t __nonnull))ensureOn NS_REFINED_FOR_SWIFT; +/** + Wait until the promise is resolved. + + @return Value if fulfilled or error if rejected. + */ +- (id __nullable)wait NS_REFINED_FOR_SWIFT; + /** Create a new promise with an associated resolver. diff --git a/Sources/AnyPromise.m b/Sources/AnyPromise.m index af6631004..3725beacd 100644 --- a/Sources/AnyPromise.m +++ b/Sources/AnyPromise.m @@ -112,6 +112,10 @@ - (id)__d { }; } +- (id)wait { + return [d __wait]; +} + - (BOOL)pending { return [[d valueForKey:@"__pending"] boolValue]; } diff --git a/Sources/AnyPromise.swift b/Sources/AnyPromise.swift index 5dfa1df4c..3702db293 100644 --- a/Sources/AnyPromise.swift +++ b/Sources/AnyPromise.swift @@ -61,6 +61,26 @@ import Foundation })) } + @objc public func __wait() -> Any? { + if Thread.isMainThread { + conf.logHandler(.waitOnMainThread) + } + + var result = __value + + if result == nil { + let group = DispatchGroup() + group.enter() + self.__pipe { obj in + result = obj + group.leave() + } + group.wait() + } + + return result + } + /// Internal, do not use! Some behaviors undefined. @objc public func __pipe(_ to: @escaping (Any?) -> Void) { let to = { (obj: Any?) -> Void in diff --git a/Tests/CoreObjC/AnyPromiseTests.m b/Tests/CoreObjC/AnyPromiseTests.m index ebe41c0af..9c93e51df 100644 --- a/Tests/CoreObjC/AnyPromiseTests.m +++ b/Tests/CoreObjC/AnyPromiseTests.m @@ -757,6 +757,22 @@ - (void)test_60_catch_on_specific_queue { [self waitForExpectationsWithTimeout:1 handler:nil]; } +- (void)test_61_wait_for_value { + id o = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) { + resolve(@1); + }].wait; + + XCTAssertEqualObjects(o, @1); +} + +- (void)test_62_wait_for_error { + NSError* err = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) { + resolve([NSError errorWithDomain:@"a" code:123 userInfo:nil]); + }].wait; + + XCTAssertEqual(err.code, 123); +} + - (void)test_properties { XCTAssertEqualObjects([AnyPromise promiseWithValue:@1].value, @1); XCTAssertEqualObjects([[AnyPromise promiseWithValue:dummyWithCode(2)].value localizedDescription], @"2");