From d02c766cde7e27d50cd70f8ae651f28c3503a776 Mon Sep 17 00:00:00 2001 From: alan Date: Mon, 10 Dec 2018 22:34:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dpromise.all=E7=9A=84=E5=86=85?= =?UTF-8?q?=E5=AD=98=E6=B3=84=E9=9C=B2=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AYPromise.podspec | 2 +- AYPromise/Classes/AYPromise.h | 6 ++-- AYPromise/Classes/AYPromise.m | 22 ++++++++---- .../AppIcon.appiconset/Contents.json | 25 +++++++++++++ Example/Tests/PromiseTest.m | 35 ++++++++++++++++--- 5 files changed, 75 insertions(+), 15 deletions(-) diff --git a/AYPromise.podspec b/AYPromise.podspec index 93ea78b..dc536f5 100644 --- a/AYPromise.podspec +++ b/AYPromise.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'AYPromise' - s.version = '1.1.5' + s.version = '1.1.6' s.summary = 'Promise for objective-c.' s.homepage = 'https://github.com/alan-yeh/AYPromise' diff --git a/AYPromise/Classes/AYPromise.h b/AYPromise/Classes/AYPromise.h index c5f7599..bd1b34d 100644 --- a/AYPromise/Classes/AYPromise.h +++ b/AYPromise/Classes/AYPromise.h @@ -17,10 +17,10 @@ FOUNDATION_EXPORT NSString * const AYPromiseInternalErrorsKey; * @param localizedDescription 错误描述 * @param internalErrors 内部错误,通过error.userInfo[AYPromiseInternalErrorsKey]可以获得 */ -NSError *NSErrorMake(id _Nullable internalErrors, NSString *localizedDescription, ...) NS_FORMAT_FUNCTION(2,3); -NSError *NSErrorWithUserInfo(NSDictionary *userInfo, NSString *localizedDescription, ...) NS_FORMAT_FUNCTION(2,3); +FOUNDATION_EXPORT NSError *NSErrorMake(id _Nullable internalErrors, NSString *localizedDescription, ...) NS_FORMAT_FUNCTION(2,3); +FOUNDATION_EXPORT NSError *NSErrorWithUserInfo(NSDictionary *userInfo, NSString *localizedDescription, ...) NS_FORMAT_FUNCTION(2,3); -NSInvocation *NSInvocationMake(id target, SEL action); +FOUNDATION_EXPORT NSInvocation *NSInvocationMake(id target, SEL action); typedef void (^AYResolve)(id __nullable result); diff --git a/AYPromise/Classes/AYPromise.m b/AYPromise/Classes/AYPromise.m index 4efc467..ed1461c 100644 --- a/AYPromise/Classes/AYPromise.m +++ b/AYPromise/Classes/AYPromise.m @@ -103,13 +103,14 @@ static id __execute__(id target, id args){ } @interface AYPromise() -@property (nonatomic) dispatch_queue_t barrier; +//@property (nonatomic) dispatch_queue_t barrier; @property (nonatomic, strong) id value; @property (nonatomic, strong) NSMutableArray *handlers; @property (nonatomic, assign) AYPromiseState state; @end @implementation AYPromise +static dispatch_queue_t _barrier = nil; - (dispatch_queue_t)barrier{ return _barrier ?: (_barrier = dispatch_queue_create("cn.yerl.promise.barrier", DISPATCH_QUEUE_CONCURRENT)); } @@ -262,7 +263,10 @@ @implementation AYPromise (CommonJS) NSAssert(isArray(promises), @"all can only hand array"); __block int64_t totalCount = [promises count]; + NSMutableArray *holders = [NSMutableArray arrayWithArray:promises]; + for (__strong id promise in promises) { + if (!isPromise(promise)) { promise = AYPromise.resolve(promise); } @@ -273,11 +277,12 @@ @implementation AYPromise (CommonJS) userInfo:@{NSLocalizedDescriptionKey: [result localizedDescription], AYPromiseInternalErrorsKey: result}]); }else if (OSAtomicDecrement64(&totalCount) == 0){ - id results = [NSMutableArray new]; - for (AYPromise *promise in promises) { + NSMutableArray *results = [NSMutableArray new]; + for (AYPromise *promise in holders) { id value = isPromise(promise) ? [promise value] : promise; [results addObject:value ?: [NSNull null]]; } + [holders removeAllObjects]; resolve(results); } }]; @@ -292,18 +297,23 @@ @implementation AYPromise (CommonJS) return [[AYPromise alloc] initWithResolver:^(AYResolve resolve) { __block int64_t totalCount = [promises count]; + NSMutableArray *holders = [NSMutableArray arrayWithArray:promises]; + for (__strong id promise in promises) { if (!isPromise(promise)) { promise = [[AYPromise alloc] initWithValue:promise]; } + [promise pipe:^(id result) { if (!isError(result)) { + [holders removeAllObjects]; resolve(result); - }else if (OSAtomicDecrement64(&totalCount) == 0){ - id errors = [NSMutableArray new]; - for (AYPromise *promise in promises) { + } else if (OSAtomicDecrement64(&totalCount) == 0){ + NSMutableArray *errors = [NSMutableArray new]; + for (AYPromise *promise in holders) { [errors addObject:isPromise(promise) ? [promise value] : promise]; } + [holders removeAllObjects]; resolve([NSError errorWithDomain:@"cn.yerl.promise" code:-1000 userInfo:@{NSLocalizedDescriptionKey: @"all promise were rejected", diff --git a/Example/AYPromise/Images.xcassets/AppIcon.appiconset/Contents.json b/Example/AYPromise/Images.xcassets/AppIcon.appiconset/Contents.json index eeea76c..d8db8d6 100644 --- a/Example/AYPromise/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/Example/AYPromise/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,15 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "idiom" : "iphone", "size" : "29x29", @@ -30,6 +40,16 @@ "size" : "60x60", "scale" : "3x" }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, { "idiom" : "ipad", "size" : "29x29", @@ -64,6 +84,11 @@ "idiom" : "ipad", "size" : "83.5x83.5", "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" } ], "info" : { diff --git a/Example/Tests/PromiseTest.m b/Example/Tests/PromiseTest.m index 4f9188f..912f9a3 100644 --- a/Example/Tests/PromiseTest.m +++ b/Example/Tests/PromiseTest.m @@ -158,8 +158,8 @@ - (void)testPipe{ - (void)testPromiseAll{ id ex1 = [self expectationWithDescription:@""]; - AYPromise *p1 = AYPromiseWithResolve(^(AYResolve _Nonnull resolve) { - XCTAssertEqual([NSThread currentThread].isMainThread, YES); + AYPromise *p1 = AYPromiseAsyncWithResolve(^(AYResolve _Nonnull resolve) { + XCTAssertEqual([NSThread currentThread].isMainThread, NO); resolve(@"thread1"); }); @@ -168,10 +168,35 @@ - (void)testPromiseAll{ resolve(@"thread2"); }); - AYPromise.all(@[@"1", p1, p2]).then(^(NSArray *result){ - BOOL isEqual = [result isEqualToArray:@[@"1", @"thread1", @"thread2"]]; + AYPromise *p3 = AYPromiseAsyncWithResolve(^(AYResolve _Nonnull resolve) { + XCTAssertEqual([NSThread currentThread].isMainThread, NO); + resolve(@"thread3"); + }); + + AYPromise *p4 = AYPromiseWithResolve(^(AYResolve _Nonnull resolve) { + XCTAssertEqual([NSThread currentThread].isMainThread, YES); + resolve(@"thread4"); + }); + + AYPromise *p5 = AYPromiseAsyncWithResolve(^(AYResolve _Nonnull resolve) { + XCTAssertEqual([NSThread currentThread].isMainThread, NO); + resolve(@"thread5"); + }); + + AYPromise *p6 = AYPromiseWithResolve(^(AYResolve _Nonnull resolve) { + XCTAssertEqual([NSThread currentThread].isMainThread, YES); + resolve(@"thread6"); + }); + + AYPromise.all(@[p1, p2, p3, p4, p5, p6]).then(^(NSArray *result){ + NSLog(@"%@", result); + BOOL isEqual = [result isEqualToArray:@[@"thread1", @"thread2", @"thread3", @"thread4", @"thread5", @"thread6"]]; XCTAssert(isEqual); [ex1 fulfill]; + }).catch(^(NSError *error){ + NSLog(@"error"); + }).always(^{ + NSLog(@"always"); }); [self waitForExpectationsWithTimeout:TIME_OUT handler:nil]; @@ -272,4 +297,4 @@ - (void)testThenInvocation{ [self waitForExpectationsWithTimeout:TIME_OUT handler:nil]; } -@end \ No newline at end of file +@end