mxcl / promisekit Goto Github PK
View Code? Open in Web Editor NEWPromises for Swift & ObjC.
License: MIT License
Promises for Swift & ObjC.
License: MIT License
short of adding:
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
static NSMethodSignature *NSMethodSignatureForBlock(id block) {
...
}
#pragma GCC diagnostic pop
to the file, anyway to get this function to play nice with -Wunused-function ? Driving me crazy.
We are regularly getting exceptions like the below reported from testers' devices. We're doing a pretty normal call with dispatch_promise.then.then... with nothing that should be too weird. A few steps return regular objects and a few return promises.
I'm not sure what else to include that might be useful. We're using
pod 'PromiseKit/base', '~>0.9.8'
pod 'PromiseKit/Foundation', '~>0.9.8'
Thanks for the help & promisekit looks great--I'll clean up and contribute back wrappers for some libraries we use soon.
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR at 0x818caf1c
Crashed Thread: 0
Application Specific Information:
objc_msgSend() selector name: addObject:
Thread 0 Crashed:
0 libobjc.A.dylib 0x3b154626 objc_msgSend + 6
1 Treasure 0x0023ccc9 __20-[PMKPromise thenOn]_block_invoke26 (PromiseKit.m:176)
2 Treasure 0x0023bb6b __18-[PMKPromise then]_block_invoke (PromiseKit.m:150)
3 Treasure 0x0002fc2b -[TrAppDelegate applicationWillEnterForeground:] (TrAppDelegate.m:311)
4 UIKit 0x3334ec77 -[UIApplication _sendWillEnterForegroundCallbacks] + 92
5 UIKit 0x332f41b5 -[UIApplication _handleApplicationResumeEvent:] + 1146
6 UIKit 0x330f3085 -[UIApplication handleEvent:withNewEvent:] + 1870
7 UIKit 0x330f2871 -[UIApplication sendEvent:] + 70
8 UIKit 0x33156cc9 _UIApplicationHandleEvent + 614
9 GraphicsServices 0x3575faed _PurpleEventCallback + 606
10 GraphicsServices 0x3575f6d7 PurpleEventCallback + 32
11 CoreFoundation 0x3089cab7 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 32
12 CoreFoundation 0x3089ca53 __CFRunLoopDoSource1 + 344
13 CoreFoundation 0x3089b227 __CFRunLoopRun + 1396
14 CoreFoundation 0x30805f0f CFRunLoopRunSpecific + 520
15 CoreFoundation 0x30805cf3 CFRunLoopRunInMode + 104
16 GraphicsServices 0x3575e663 GSEventRunModal + 136
17 UIKit 0x3315116d UIApplicationMain + 1134
18 Treasure 0x000690cb main (main.m:31)
19 libdyld.dylib 0x3b657ab7 start + 0
turning void blocks into [NSNull null], would make promises that fulfill or reject to nothing, work well when used with promise aggregators like all
Supporting void blocks would be nice, especially for methods that aggregate promises.
Why does PromiseKit propagate exceptions (instances of the class NSException
) to clients? Wouldn't it be more appropriate to follow the Cocoa convention of using errors (instances of the class NSError
) exclusively to indicate failure?
Since clients rescue from erros instead of catch exceptions, I suggest to rename -[Promise catch]
to -[Promise rescue]
or -[Promise error]
. If clients write code that throws exceptions, it is the clients fault that should be handled during development. Error handling at runtime should not occur by catching exceptions.
The Error Handling Programming Guide - A Note on Errors and Exceptions states the following:
It is important to keep in mind the difference between error objects and exception objects in Cocoa and Cocoa Touch, and when to use one or the other in your code. They serve different purposes and should not be confused.
Exceptions (represented by NSException objects) are for programming errors, such as an array index that is out of bounds or an invalid method argument. User-level errors (represented by NSError objects) are for runtime errors, such as when a file cannot be found or a string in a certain encoding cannot be read. Conditions giving rise to exceptions are due to programming errors; you should deal with these errors before you ship a product. Runtime errors can always occur, and you should communicate these (via NSError objects) to the user in as much detail as is required.
Although exceptions should ideally be taken care of before deployment, a shipped application can still experience exceptions as a result of some truly exceptional situation such as “out of memory” or “boot volume not available.” It is best to allow the highest level of the application—the global application object itself—to deal with these situations."
Let me know what you think.
It is currently required to pass an argument to the fulfiller callback, as per the callback's signature:
typedef void (^PMKPromiseFulfiller)(id);
However, I find that I often don't need to pass any arguments at all. Any chance we can accommodate this use case somehow?
My Objective-C isn't fantastic, so I might be totally wrong about this.
But I have some promise experience
Anyways, a quick skim leaves me concerned:
Given: a settled promise, https://github.com/mxcl/PromiseKit/blob/master/PromiseKit.m#L137 appears to synchronously invoke the callback of a chained then.
This would be a serious departure from the spec.
The callbacks must not be invoked until the execution context stack is once again fresh.
see: https://github.com/promises-aplus/promises-spec#the-then-method specifically point 4. Without this, we unleash Zalgo onto our code base.
How can I check whether a given Promise is in Pending or Resolved state? I'm looking at http://blog.popularpays.com/tech/2014/4/28/popular-promises and those guys are accessing a property called 'pending' on a Promise, but it seems it does not exist in the HEAD version.
- (Promise *)poll {
if (self.poller.pending)
return self.poller;
I can see a private macro defined in PromiseKit.m, but nothing else that I can use publicly.
#define IsPending(o) (((Promise *)o)->result == nil)
First of all, thank you for the great library! Using it is like a breeze!
I'm using PromiseKit in an IOS app to communicate with a Rails RESTful backend,
and there're some calls that return only header, say by executing head 200
on the backend.
What I've tried is:
I used [NSURLConnection POST:url formURLEncodedParameters:parameters]
to post data to backend, the backend did receive the data and responded with a head 200
message, but PromiseKit is reporting the following exception:
2014-07-31 11:19:39.501 HelloPOS[13223:60b] Error
Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be
completed. (Cocoa error 3840.)" (No value.) UserInfo=0xa4c5a90
{NSDebugDescription=No value., PMKURLErrorFailingDataKey=<CFData
0xa4c19d0 [0x1f60ec8]>{length = 1, capacity = 16, bytes = 0x20},
PMKURLErrorFailingURLResponseKey=<NSHTTPURLResponse: 0xa3a8170> { URL:
http://SOME_APP.SOME_HOST.com/api/v1/sales.json } { status code: 200,
headers {
"Cache-Control" = "max-age=0, private, must-revalidate";
Connection = "keep-alive";
"Content-Length" = 1;
"Content-Type" = "application/json";
Date = "Thu, 31 Jul 2014 03:19:25 GMT";
Etag = ""7215ee9c7d9dc229d2921a40e899ec5f"";
Server = "WEBrick/1.3.1 (Ruby/2.0.0/2014-05-08)";
Via = "1.1 vegur";
"X-Content-Type-Options" = nosniff;
"X-Frame-Options" = SAMEORIGIN;
"X-Request-Id" = "5a1c1aa1-4b42-41ea-8397-a5df8fa956bc";
"X-Runtime" = "0.013359";
"X-Xss-Protection" = "1; mode=block"; } }}
It's probably because header-only response has no body, and the error is caused
PS: I've changed the URL in the exception message
So the problem is: Is it possible to handle header-only response with PromiseKit?
Hey all,
Sorry if is the wrong place to post this, but I wanted to share that I am working on a Parse+PromiseKit category.
While it's functional and nearly complete, I am not sure if I'm handling the Parse methods that return a "succeeded" boolean in the best way. I figured passing the boolean as the result was pointless because promises can already tell us if a task succeeded for failed. That means if the boolean is passed as the result, thens would always receive YES.
Instead, I figured it would be much more helpful to have the object the task succeeded on. For example [object promiseSave]
would then object
(or self
) so that you could read the object/data that was just saved. Similarly, [PFObject promiseSaveAll:]
thens the array of objects that were saved, rather than the redundant YES boolean. But if I do this for some methods, should I do it for all (then the object(s) the task operated on)? It seems inconsistent just to do it for some. Thoughts, anyone?
Feel free to contribute. Once the documentation is completed and README revised, I'll see if this can be added to the Parse podspec. Otherwise I'll submit as a separate pod.
Thanks!
One thing I noticed when using PromiseKit is that if you want to have a catch that doesn't continue on to a chained then
after it runs, you must explicitly return the NSError
at the end of the catch block. Lack of a return statement acts the same as return nil;
.
Another promise system I used (a hand-built one we had at a former company — it was written in Lua, but semantically similar) would re-propagate an error automatically if there was no return
in the catch block.
Having looked at how this is implemented in PromiseKit, it seems like this could be supported by adding a distinction between PMKNull
and another value, let's call it PMKNoReturn
, internally and handling them differently in catch
.
PromiseKit cannot find the Foundation.NSOperation
module with Xcode 6.
Just wonder if there is possible to integrate PromiseKit with AF?
Has anyone started working on a Parse implementation? If so I'm interested in contributing, please let me know.
If you return nil from a then block, the block never gets executed.
myPromise.then(^{
// do something - this will never execute
return nil;
});
Put this works just fine.
myPromise.then(^{
// do something - this will execute
});
The docs do mention
Not returning from a catch handler (or returning nil) causes PromiseKit to consider the Promise complete. No further bubbling occurs.
which is similar, but in our case the then block still executes if the return type is void; it just doesn't like nil.
If this is by design, it should be mentioned in the docs. I've been converting a project from Bolts and my continue (then) blocks often return nil as the block signature (BFContinuationBlock) has a return type of id.
[[self saveAsync:obj] continueWithBlock:^id(BFTask *task) {
if (task.isCancelled) {
// the save was cancelled.
} else if (task.error) {
// the save failed.
} else {
// the object was saved successfully.
PFObject *object = task.result;
}
return nil; // Bolts requires you to return something.
// Doing this in PromiseKit will cause the block to never execute.
}];
Can it be more than just one parameter in fulfiller block?
For example I have block with signature like that:
void (^successBlock)(RKObjectRequestOperation *, RKMappingResult *)
pod update
)The afflicting file: https://github.com/mxcl/PromiseKit/blob/3b0e805340c27c208a3a0f8825fa07858e651e21/objc/UIActionSheet%2BPromiseKit.h
#import <PromiseKit/fwd.h>
#import <UIKit/UIActionSheet.h>
@interface UIActionSheet (PromiseKit)
/**
Thens the dismissedButtonIndex and the actionSheet itself as the second
parameter. This promise will never be rejected.
*/
- (PMKPromise *)promiseInView:(UIView *)view;
@end
I am showing the result of version 0.9.15.2
above.
Tested Versions:
The default dispatch_promise
runs the promise on a background thread. There is dispatch_promise_on
, which would allow me to select the main queue, but I feel that a convenience method for this makes the most sense, something like dispatch_promise_on_main
or dispatch_promis_main
.
Why? Because another great use of promises is to make UI Animations easy to work with. For example, in my game I have the following code:
/// Did Opponent Guy Faint?
if ([self isOpponentDead]) {
// make him faint
[self opponentFaintWithCallback:^{
NSString *text = [NSString stringWithFormat:@"%@ fainted!", self.currentOpponent.name];
[self showText:text untilDismissed:^{
NSInteger expGain = [self.currentOpponent experienceGainedWhenDefeated];
NSDictionary *levelInfo = [self.currentPlayer gainExperience:expGain];
/// if you grew a level OR if you need to delete a move, do all that.
NSString *exp = [NSString stringWithFormat:@"%@ got %d exp points!", self.currentPlayerGuy.name, expGain];
[self showText:exp untilDismissed:^{
if (levelInfo != nil) {
NSString *lvlUp = [NSString stringWithFormat:@"%@ grew to level %d!", self.currentPlayerGuy.name,
self.currentPlayerGuy.level.integerValue];
[self updateLabels:NO];
[self showText:lvlUp untilDismissed:^{
if ([levelInfo[@"moves"] count] > 0) {
Move *m = [levelInfo[@"moves"] lastObject];
NSString *learned = [NSString stringWithFormat:@"%@ learned %@!", self.currentPlayerGuy.name, m.name];
[self showText:learned untilDismissed:^{
if (self.currentPlayerGuy.moves.count > 10) {
DLog(@"... we... need to delete a move.");
[self opponentSendOutNextEnemyWithCallback:^(BOOL didSendOut) {
if (!didSendOut) {
[self opponentLosingSequence];
} else {
[self emptyMoveQueue];
[self showMainMenu];
}
}];
} else {
[self opponentSendOutNextWithCallback:^(BOOL didSendOut) {
if (!didSendOut) {
[self opponentLosingSequence];
} else {
[self emptyMoveQueue];
[self showMainMenu];
}
}];
}
}];
} else {
[self opponentSendOutNextWithCallback:^(BOOL didSendOut) {
if (!didSendOut) {
[self opponentLosingSequence];
} else {
[self emptyMoveQueue];
[self showMainMenu];
}
}];
}
}];
} else {
[self opponentSendOutNextWithCallback:^(BOOL didSendOut) {
if (!didSendOut) {
[self opponentLosingSequence];
} else {
[self emptyMoveQueue];
[self showMainMenu];
}
}];
}
}];
}];
}];
return;
}
Oh my god, it's hideous. Promises will make this sequence much, much better, but all the animations should run on the main thread - the promise implementation is just a wonderful way to handle the asynchronous nature of the entire thing. Showing text, waiting for them to dismiss it, etc.
If you think this is a good idea, I can go ahead and add a pull request.
PromiseKit.m line 249:
[handlers addObject:^(id passthru){
handlers can end up nil, and then fails to addObject
My use case (no 'then', first app load after install):
[SomePromise]
.catch(^(NSError *error) { NSLog(@"error: %@",error); } )
.finally(^() { //show screen no matter what } );
have also commented out catch
and can repeat, usually 1/2 tries.
I'm using PromiseKit for an app I'm currently developing. By looking for leaks inside the app from Instruments, I realized that every time I call [PMKPromise new]
I get a leak.
The following is the function call that leaks (PMKPromise:385):
this->_promiseQueue = PMKCreatePromiseQueue();
Any idea of why that is?
For cleanup, it's often useful to register a callback that runs whenever the future resolves or rejects.
e.g.
[Promise until:^{ return tryAcquireRemoteLock(connectedSocket); }]
catch:^{ return nil; }]
.finally(^{ [socket close]; });
One of the things that Bolts does pretty well is let you choose a queue to run a block on, while this is manual with PromiseKit. I think it'd be useful to be able to write:
dispatch_queue_t queue = ...;
dispatch_promise(queue, ^{
return [self makeValueAsync];
}).then(dispatch_get_main_queue(), ^(id value) {
[self.view displayValue:value];
return [self logDisplayInfo:self.view];
}).then(^{
// No queue specified: synchronously run on the same queue immediately after
// logDisplayInfo's promise is resolved
});
Also Bolts has an "executor" abstraction that runs blocks. Executors might be more general than needed but the default executors are useful to have:
The main case is thread safety for the same pending promise when then
ing from multiple threads.
Otherwise a thorough review should be done to check everything else is safe. Mostly due to our use of GCD and the immutability of resolved promises, we're good.
Hey, I'm using the Swift variant of PromiseKit and playing around. I would really enjoy having a richer API namely:
Promise<T>.resolve(x:T) -> Promise<T>
which creates a resolved promise with the value x. Today this is done with Promise(x)
which I believe is more ambiguous.Promise<T>.reject(e:NSError) -> Promise<T>
which creates a rejected promise with the reason ePromise.all(a:Promise<A>,b:Promise<B>,c:Promise<C>) -> Promise<(A,B,C)>
and similarly overloads for 1 to 8 arguments, creates a promise that fulfills when they all fulfill or rejects when one rejects similarly to JavaScript's Promise.all
, since Swift has no macros and arrays are homogenically typed this is a lot of repetition but very useful.Promise<T>.all(arr:[Promise<T>]) -> Promise<[T]>
- takes an array of promises and returns a single promise that fulfills when they all fulfill and rejects when either one rejects. This is the "variable length" version of all from above but it requires all promises to have the same type.Promise<[T]>.map(fn:(T) -> Promise<U>) -> Promise<U>
- maps an array of promises each to a promise and resolves when they all resolve, similar to returning a map of the array in the .then
.Other than that - great work! Coming from JS PromiseKit is really nice to work with.
Some Promise libraries support the addition of a progress
handler. It is meant for communicating progress in long-running operations (some more discussion here).
What are your thoughts on implementing this handler in PromiseKit? I have a specific use case that I've seen other libraries deal with using progress
handlers:
NSURLCache
. In case it does, and if the user explicitly sets it (via a new NSURLRequestCachePolicy
), the request serves the cached data and then fetches from the network anyway. This is so that the user gets potentially stale data immediately while fresh data is being fetched in the background.I would possibly like to use progress
to support this use case, serving the cached data through this handler and then the final, fresh, data through the normal fulfillment
handler.
Other than using progress
, do you see any potential way of supporting this behaviour using just the two currently supported handlers?
Thank you!
Refs #59
Hi, I was wondering if this implementation complies (or intends to) with the Promises/A+ specification http://promisesaplus.com/
I think this is something worth clarifying too.
Looks like really nice work by the way, good luck.
P.S
I'm also wondering why you chose to use the 'old' promise construction style (Deferred) rather than the new one (Promise constructor), thanks.
I thought that swift incorrectly define type of a closure, but casting doesn't help.
Example from README.md doesn't work for me as well.
Is it bug, or i'm doing something wrong?
let promise: Promise<Int> = Promise({ success, failure in
success(10)
})
promise.then { number in
self.remainingTimeLabel.text = "int is \(number)"
}.catch { error in
self.remainingTimeLabel.text = "erorr is \(error)"
}
https://github.com/mxcl/PromiseKit/blob/master/PromiseKit.m#L260-L261 seems to indicate that an exception is thrown if the promise is rejected or fulfilled once its fate has become sealed. Actually, it should merely "black hole" the attempt, remain sealed to it's original fate.
if the promise has settled, but its resolution value is falsey, the promise is assumed to not have settled, and we merely queue another follower:
https://github.com/mxcl/PromiseKit/blob/master/PromiseKit.m#L136
Likely tracking internal state separately of fulfillment type would help.
I have an NSMutableArray that I add promises to and then call +when:
to generate a new promise when all the promises have fulfilled. However, when the array contains no promises, +when:
never fulfills.
Simple example:
Promise* p = [Promise when:@[]];
p.then(^{
NSLog(@"here empty");
});
Promise* p2 = [Promise when:@[
[Promise promiseWithValue:@"hi"]
]];
p2.then(^{
NSLog(@"here with one");
});
Expected:
here empty
here with one
Actual:
here with one
This is easily fixed by adding the following to the top of +all:
if (count == 0)
return [Promise promiseWithValue:@[]];
If you agree with the scenario, I'll fire off a PR.
dispatch_promise(^{
return 3;
}).then(^(NSInteger i) {
// …
});
This crashes here since the return type is obviously not id
.
I don't know what's the cleanest way to solve this. It's kind of acceptable that primitive types don't work. Maybe even leave it as-is and update the docs, or start supporting it?
(I caught this when accidentally returning "string"
instead of @"string"
. 🙈)
Is it possible to unwrap a variable that has been wrapped through PMKManifold?
I'm doing something like this:
-(void)cachedList:(Class)providerClass deleteOrphanedObjects:(BOOL)deleteOrphanedObjects success:(void (^)(NSArray *result))success failure:(void (^)(NSString *error))failure {
ALTCachedRequest *gr = [[ALTCachedRequest alloc] init];
gr.cacheKey = @"";
ALTBaseProvider *provider = [[providerClass alloc] initWithDatabaseController:_database andRequestOperationManager:_manager andBaseURL:WSBaseURL];
provider.deleteOrphanedObjects = deleteOrphanedObjects;
provider.request = gr;
[provider fetchData].then(^(NSArray *cachedData, PMKPromise *freshData) {
success(cachedData);
return freshData;
}).then(^(NSArray *freshData) {
success(freshData);
}).catch(^(NSError *error) {
failure([error localizedDescription]);
});
}
and the provider fetchData method is this one:
- (PMKPromise *)fetchData {
return dispatch_promise(^{
id fresh = [self downloadDataFromWS];
id cached = [self fetchObjectsFromDb];
return PMKManifold(cached, fresh);
});
}
and fetchObjectsFromDb
is this one:
- (PMKPromise *)fetchObjectsFromDb {
return [PMKPromise new:^(PMKPromiseFulfiller fulfiller, PMKPromiseRejecter rejecter) {
[self.database fetchLabels].then(^(id res) {
fulfiller(res);
});
}];
}
The cachedData
object being returned, which should be an NSArray *
is actually a PMKPromise *
. From the documentation I take it should actually be the type I set in the arguments of then
, but it looks like I'm missing something.
Thanks!
Hey, just checked out the library - wanted to say thanks for the awesome work! Enjoyed learning about it. :) Didn't see an issue about this here, so I thought you might want to know... PromiseKit can't be imported into any file which includes Objective-C++. Try creating a .mm file and importing it. It's due to PromiseKit's usage of @import syntax rather than #import, which objective-c++ may not support right now.
Consider an asynchronous HTTP GET method request that returns a promise:
- (Promise*)GET:(NSString*)path;
Users of this API may want to cancel the underlying asynchronous work, the HTTP request. Currently PromiseKit does not allow cancelable promises.
I've been looking into javascript promises and cancelation. There is some discussion in the A+ spec https://github.com/promises-aplus/cancellation-spec/issues
Any thoughts on cancelation?
Wrapping e.g. Parse
- (Promise *)allUsers {
return [Promise new:^(PromiseResolver fulfiller, PromiseResolver rejecter){
PFQuery *query = [PFQuery queryWithClassName:@"User"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
fulfiller(objects);
} else {
rejecter(error);
}
}];
}];
}
I believe this should be
return [Promise new:^(PromiseFulfiller fulfiller, PromiseRejecter rejecter) {
now that PromiseResolver is deprecated
Would be useful to have these analogues to thenOn.
In + (Promise *)new:(void(^)(PromiseResolver, PromiseResolver))block
:
id rejecter = ^(id error){
if (promise->result)
@throw PMKE(@"Promise already fulfilled/rejected");
if ([error isKindOfClass:[Promise class]])
@throw PMKE(@"You may not reject a Promise");
if (!error)
error = [NSError errorWithDomain:PMKErrorDomain code:PMKErrorCodeUnknown userInfo:nil];
if (![error isKindOfClass:[NSError class]])
error = NSErrorWithThrown(error);
NSLog(@"PromiseKit: %@", error); // we refuse to let errors die silently
promise->result = error;
RejectRecursively(promise);
};
Why is the NSLog statement there. The comment implies that we don't want to have errors silently lost via promises. But in this case the error hasn't had a chance to be caught and properly handled.
Perhaps I'm misreading this code, but shouldn't we wait for RejectRecrusively to execute before declaring the error silently missed?
although it might appear strange, one should be able to resolve with an error, and the promise should be in fulfilled state.
Again, I suspect keeping track of the promises fate independent of its resolution value (or reason);
For example I have 3 HTTP requests executing in turn.
Because we are using ASI-HTTP (unfortunately), how can I make use of PromiseKit to implement it?
I have seen the AFNetworking example, which return new Promise object with block, but ASI is delegate based, I have no idea how to implement the new Promise interface.
Thanks.
This would be really useful to reduce silent failures. One of the roughest things about Promises (compared to C#/HHVM async functions) is that unhandled exceptions get swallowed. Many Promise implementations can't do much about this since someone could add a "catch" handler in the future. In Objective-C, though, we know that no one is going to add a handler after a Promise has been deallocated.
In older API if we use methods like when
that take multiple promises, we would get NSArray
of sub-errors + results, right now we only get a single NSError
. Now I like cleaner distinction between error and results but right now there is no way to know which promise failed, which complicates things when you care or can recover from some errors.
One can wrap each promise into a catch
statement before using aggregate method but it might be much more complicated code in many cases.
It would be useful to be able to query which promise failed, what do you think?
This is a great looking, idiomatic framework, but it seems to have broken w/Beta 4
This code does not compile
public func renewCredentials(account:Int) -> Promise {
return Promise { (fulfiller, rejecter) in
}
}
when it is inside the PromiseKit module, it does compile.
Returning PMKManifold and NSError within a promise block without casting them to id results in the following error being reported on build:
Return type 'id' must match previous return type 'PMKArray *' when block literal has unspecified explicit return type
This seems to occur mainly within a .then() block. Any ideas what I should be doing differently?
Hey @mxcl,
I was looking through the source code and felt a bit surprised around how the unit tests are structured for PromiseKit.
Can you shed some light on why the unit tests are structured, compiled and run the way they are?
Cheers!
:D Could that function be renamed?
https://github.com/mxcl/PromiseKit/blob/master/PromiseKit.m#L19
This error came when updating PromiseKit to version 0.9.14.2. Seems like the PromiseKit+When.h-Header isn´t imported anywhere in the build process.
When going back to 0.9.13.2, it works again.
Please change Promise
and Deferred
classes to PKPromise
and PKDeferred
or similar to minimize the chance of class name conflicts.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.