Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Alan Yeh committed Jul 22, 2016
0 parents commit b8f8661
Show file tree
Hide file tree
Showing 33 changed files with 2,436 additions and 0 deletions.
33 changes: 33 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# OS X
.DS_Store

# Xcode
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
xcuserdata/
*.xccheckout
profile
*.moved-aside
DerivedData
*.hmap
*.ipa

# Bundler
.bundle

Carthage
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
#
# Note: if you ignore the Pods directory, make sure to uncomment
# `pod install` in .travis.yml
#
Pods/
14 changes: 14 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# references:
# * http://www.objc.io/issue-6/travis-ci.html
# * https://github.com/supermarin/xcpretty#usage

osx_image: xcode7.3
language: objective-c
cache: cocoapods
podfile: Example/Podfile
before_install:
- gem install cocoapods
- pod install --project-directory=Example
script:
- set -o pipefail && xcodebuild test -workspace Example/AYPromise.xcworkspace -scheme AYPromise-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty
- pod lib lint
42 changes: 42 additions & 0 deletions AYPromise.podspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#
# Be sure to run `pod lib lint AYPromise.podspec' to ensure this is a
# valid spec before submitting.
#
# Any lines starting with a # are optional, but their use is encouraged
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html
#

Pod::Spec.new do |s|
s.name = 'AYPromise'
s.version = '1.0.0'
s.summary = 'Promise for objective-c.'

# This description is used to generate tags and improve search results.
# * Think: What does it do? Why did you write it? What is the focus?
# * Try to keep it short, snappy and to the point.
# * Write the description between the DESC delimiters below.
# * Finally, don't worry about the indent, CocoaPods strips it!

# s.description = <<-DESC
# TODO: Add long description of the pod here.
# DESC

s.homepage = 'https://github.com/alan-yeh/AYPromise'
# s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { 'Alan Yeh' => '[email protected]' }
s.source = { :git => 'https://github.com/alan-yeh/AYPromise.git', :tag => s.version.to_s }
# s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>'

s.ios.deployment_target = '6.0'

s.source_files = 'AYPromise/Classes/**/*'

# s.resource_bundles = {
# 'AYPromise' => ['AYPromise/Assets/*.png']
# }

# s.public_header_files = 'Pod/Classes/**/*.h'
# s.frameworks = 'UIKit', 'MapKit'
# s.dependency 'AFNetworking', '~> 2.3'
end
Empty file added AYPromise/Assets/.gitkeep
Empty file.
Empty file added AYPromise/Classes/.gitkeep
Empty file.
121 changes: 121 additions & 0 deletions AYPromise/Classes/AYPromise.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
//
// AYPromise.h
// AYPromise
//
// Created by PoiSon on 16/2/15.
// Copyright © 2016年 PoiSon. All rights reserved.
//

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

FOUNDATION_EXPORT NSString * const AYPromiseInternalErrorsKey;
/**
* 快速构建NSError对象
*
* @param localizedDescription 错误描述
* @param internalErrors 内部错误,通过error.userInfo[AYPromiseInternalErrorsKey]可以获得
*/
FOUNDATION_EXPORT NSError *NSErrorMake(id _Nullable internalErrors, NSString *localizedDescription, ...) NS_FORMAT_FUNCTION(2,3);

typedef void (^PSResolve)(id __nullable result);

typedef NS_ENUM(NSUInteger, AYPromiseState) {
AYPromiseStatePending = 1 << 0, /**< 待执行状态 */
AYPromiseStateFulfilled = 1 << 1, /**< 成功状态 */
AYPromiseStateRejected = 1 << 2 /**< 失败状态 */
};

@interface AYPromise<ValueType> : NSObject
- (instancetype)init __attribute__((unavailable("不允许直接实例化")));
+ (instancetype)new __attribute__((unavailable("不允许直接实例化")));

@property (nonatomic, readonly, assign) AYPromiseState state; /**< Promise当前状态 */
@property (nonatomic, readonly) id value; /**< Promise的执行结果,失败时,执行结果为NSError对象 */
@end

/**
* CommonJS Promise/A 标准接口
*/
@interface AYPromise (CommonJS)
/**
* 接受的参数如果是Promise对象就直接返回
* 如果参数是NSError对象,就会生成一个失败态(rejected)的promise,并传递给之后的catch
* 参数为其它的值则生成一个成功态(fulfilled)的promise,并传递给之后的then
*/
+ (AYPromise *(^)(id _Nullable value))resolve;

/**
* AYPromise.all用来包装一系列的promise对象,返回一个包装后的promise对象,我们称之为A
* 1. 当所有的promise对象都变成成功态(fulfilled)后,这个包装后的A才会把自己变成成功状态。
* A会等最慢的那个promise对象变成成功态(fulfilled)后才把自己变成成功态。
* 2. 只要其中一个promise对象变成失败态(rejected),包装后的A就变成rejected,
* 并且第一个rejected传递的值,会传递给A后面的catch。
*/
+ (AYPromise *(^)(NSArray<AYPromise *> *promises))all;

/**
* AYPromise.race用来包装一系列的promise对象,返回一个包装后的promise对象,我们称之为R
* 1. 只要其中的一个promise对象变成成功态(fulfilled)后,这个包装后的R就会变成成功态(fulfilled),
* 并且其它的promise不再执行。
* 2. 当所有的promise对象都变成失败态(rejected)后,这个包装后的R才会把自己变成失败状态。
*/
+ (AYPromise *(^)(NSArray<AYPromise *> *promises))race;

/**
* then接受成功回调
* 如果Promise对象处于预备状态就等待,直到状态改变才开始执行
* 如果Promise对象处于成功态,再用then添加回调就直接调用对应的回调
* 如果then的返回值不是Promise,会作为下一个then的参数
* 如果then的返回值是Promise对象,那么之后的then添加的操作函数会被托管给返回的Promise对象
* 如果value是一个Promise,则认为then的返回值是Promise对象
*/
- (AYPromise *(^)(id value))then;

/**
* catch接受失败回调
* 如果promise对象处于预备状态就等待,直到状态改变才开始执行
* 如果promise对象处于失败态,再用catch添加回调就直接调用对应的回调
* 如果catch的返回值不是promise,会作为下一个then的参数
* 如果catch的返回值是一个新的promise对象,那么之后的then添加的操作函数会被托管给新的promise对象
*/
- (AYPromise *(^)(id block))catch;
@end

/**
* 标准接口之外添加的便利方法
*/
@interface AYPromise (Extension)
- (AYPromise *(^)(id block))thenAsync;/**< 异步执行 */
- (AYPromise *(^)(NSTimeInterval delaySecond, id block))thenDelay;/**< 延迟执行 */
- (AYPromise *(^)(dispatch_queue_t queue, id block))thenOn;/**< 在指定线程执行 */
- (AYPromise *(^)(void (^resolver)(id result, PSResolve resolve)))thenPromise;/**< 需要回调的任务 */
- (AYPromise *(^)(id block))catchAsync;/**< 异步处理错误 */
- (AYPromise *(^)(dispatch_queue_t queue, id block))catchOn;/**< 在指定线程处理错误 */
- (AYPromise *(^)(id block))always;/**< 无论错误还是正确都执行 */
@end
/**
* 创建Promise对象
*
* 如果value是block,则创建一个Pending状态的Promise并同步执行block
* 如果value是Promise, 则直接返回Promise
* 如果vlaue是数组,则返回Promise.all封装的Promise
* 如果vlaue是NSError对象,则返回一个Rejected状态的Promise
* 如果vlaue是其它的对象,则返回一个Fulfilled状态的Promise
*/
FOUNDATION_EXPORT AYPromise *AYPromiseWith(_Nullable id value);
/**
* 创建Promise对象
*
* 如果value是block,则创建一个Pending状态的Promise并异步执行block
* 其它同上
*/
FOUNDATION_EXPORT AYPromise *AYPromiseAsyncWith(_Nullable id value);
/**
* 创建一个需要回调的Promise
*/
FOUNDATION_EXPORT AYPromise *AYPromiseWithResolve(void (^)(PSResolve resolve));
NS_ASSUME_NONNULL_END


Loading

0 comments on commit b8f8661

Please sign in to comment.