Git Product home page Git Product logo

ompromises's People

Contributors

aomader avatar rodrigoelp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ompromises's Issues

Analysis warning on OMDeferred.m

Hi,
I have been integrating OMPromises on our app and our code analysis tool picked up a potential problem on OMDeferred.m in the following method:

- (void)progress:(float)progress 

The initialisation of

    NSArray *progressHandlers = nil;

    @synchronized (self) {
    // ... Initialising progressHandlers with pending handlers.
    }

    @synchronized (progressHandlers) {
        for (void (^progressHandler)(float) in progressHandlers) {
            progressHandler(progress);
        }
    }

Static analysis complains about progressHandlers potentially being nil in which cast the lock will never happen and no synchronisation will happen.

Based on my understanding I think that scenario reported is not real although, couldn't we allocate an empty array to prevent this analysis issue? I have tested it and it seems to pass the tests.

Chain rescues and failures?

I've been using the chain: method quite a bit, and I was wondering if you'd thought about the ability to insert rescue and failure blocks into the chain in addition to then blocks?

retain cycle when fulfilling with self

I have have the following setup:

@property (nonatomic, strong) OMDeferred *didLoad;

{
    ..
    [self.didLoad fulfil:self];
    ..
}

The problem is now that this causes a retain cycle that I have to break by nil'ing didLoad.
Does the OMDeferred really need to hold a strong reference?

ensure fulfillments instead of assertion?

Just as an example - say I want to wait with a OMPromise chain for the first time the view did appear - which by definition this can happen multiple times. Which also is why the following code will fail.

@property(nonatomic) OMDeferred *didAppear;

- (id) init...
{
  self.didAppear = [OMDeferred deferred];
}

- (void) viewDidAppear
{
  [super viewDidAppear];
  [self.didAppear fulfil:self];
}

I guess I could work around this by checking the state of the OMPromise but I was hoping for a more elegant way of expressing this.

Podspec refinement

I'm running my application with Xcode 5 and iOS 6.0 simulator. XCTest is not supported in iOS 6.0. App will crash with this:

dyld: Library not loaded: /Developer/Library/Frameworks/XCTest.framework/XCTest
Referenced from: /Users/visavarjus/Library/Application Support/iPhone Simulator/6.0/Applications/B6B1365F-308E-49A7-B545-B8409F329643/W-ZUP.app/W-ZUP
Reason: image not found

Currently, "Tests" subspec gets installed, even though we don't need it for app targets. Maybe OMPromises.podspec should define a "core" subspec and use it as default_subspec.

Returning an fulfilled promise from then block raises assertion

When returning an already fulfilled promise from a then block an assertion gets raised causing the app to crash.

Code to test:

[[somePromise then: ^( id result ) {
   return [OMPromise promiseWithResult: @42];
}] then: ^id (id result) {
   NSLog( @"The answer: %@", result );
   return result;
}];

I know this is a rather contrived example, but I am also running into this issue in my real app.

Console output:

2014-03-16 12:47:36.369 TestApp[85851:60b] *** Assertion failure in -[OMDeferred progress:], .../Pods/OMPromises/OMPromises/OMDeferred.m:84
2014-03-16 12:51:17.389 TestApp[85851:60b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Can only progress while being Unfulfilled'
*** First throw call stack:
(
    0   CoreFoundation                      0x01cbf1e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x01a3e8e5 objc_exception_throw + 44
    2   CoreFoundation                      0x01cbf048 +[NSException raise:format:arguments:] + 136
    3   Foundation                          0x003b54de -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
    4   TestApp                             0x0002693a -[OMDeferred progress:] + 378
    5   TestApp                             0x0002820d __21-[OMPromise then:on:]_block_invoke_2 + 125
    6   TestApp                             0x00029ce6 -[OMPromise progressed:on:] + 326
    7   TestApp                             0x00029b55 -[OMPromise progressed:] + 101
    8   TestApp                             0x00028131 __21-[OMPromise then:on:]_block_invoke47 + 241
    9   TestApp                             0x0002633b -[OMDeferred fulfil:] + 571
    10  TestApp                             0x0002c944 __17+[OMPromise all:]_block_invoke186 + 260
    11  TestApp                             0x0002633b -[OMDeferred fulfil:] + 571

concurrent authentication promises

I have concurrent requests to an API. The calls to the API need to be authenticated. Each authentication request creates a new token. Now the problem is that I don't want the API to create a token per concurrent request. Only the first authentication call should lead to a request and a single token.

My callback base implementation uses a dispatch group.
Now I am looking for the right pattern when using promises.
Simple chaining does not seem to be enough here.

Any suggestions?

fulfilled

I would rename fulfilled: to succeeded:. Reads much better. Using fulfilled just because it's a promise feels like trying too hard.

Thread-safe access to [OMPromise state]

When I run my app with Xcode's Thread sanitizer enabled, I get an issue reported where read access to the 'state' property is not properly guarded (see attached screenshot). This could be fixed by either declaring the 'state' property as atomic, or by putting the read access within the @synchronized clause.

Any ideas what would be the best route to fix this?

Screen Shot 2020-01-11 at 21 22 04

Add possibility to wrap any synchronous method into an asynchronous promise

It would be good to create a promise of a synchronous method with its return value being the result of the promise. Something like the below.

OMPromise *blockResult = [OMPromise run:^{
    // that takes verryy long
    return myAwesomeResult;
}];

OMPromise *methodResult = [OMPromise call:@select(foo:) on:self];

The actual call of the method/block should be performed in a background thread and the result/failure should be deployed in the thread where the promise has been created.

Assertion fails when comparing progress

From Time to time I see assertion failure
https://github.com/b52/OMPromises/blob/master/Classes/Core/OMDeferred.m#L90
NSAssert(self.progress <= progress, @"Progress can only increase");

Even though the progress is equal.

Please have a look at this article.
http://stackoverflow.com/questions/10334688/how-dangerous-is-it-to-compare-floating-point-values

In the comments you can find explanation and solution for the issue.

My suggestion for a quick fix:
NSAssert(self.progress - progress < 0.001, @"Progress can only increase");

exception localization problem

The key error_exception_%@ cannot be found, that causes the format to be nil and gives another exception overshadowing the original one.

https://github.com/b52/OMPromises/blob/master/Classes/Core/OMResources.m#L67

Frankly speaking I don't understand how though. Quoting from the docs

A localized version of the string designated by key in table tableName. If value is nil or an empty string, and a localized string is not found in the table, returns key. If key and value are both nil, returns the empty string.

Yet I see

(lldb) po key
error_exception_%@

(lldb) po format
 nil

Any idea? Maybe just add a safe guard?

Cancel other promises when one of any composition got fulfilled

When you do
[OMPromise any:@[A, B, C]];
and e.g. B is fulfilled.
Wouldn't it be cool to cancel A and C.
It's not a big deal, but users may expect such behavior, special when there is a cancel method on promises.
Same is true for progress. If we have an any concatenation, we are done (100% progress) when any of the promises is fulfilled.

Update documentation

Add general documentation to describe the overall working procedure of OMPromise and OMDeferred.

optional promise

Another pattern question:

The API has two methods doOne and doTwo. I need the final result of both calls hence:

OMPromise *all = [OMPromise all:@[
    [[API sharedInstance] doOne],
    [[API sharedInstance] doTwo]
]];

[[all fulfilled:^(id result) {
 ...
}] failed:^(NSError *error) {
 ....
}];

Now the problem is that doTwo may fail with a 401 status code. In fact the result is optional. With the above code snippet it's required and means the whole combined promise fails, too.

I know I could wrap the doTwo in another promise that catches the error and always fulfills.

OMDeferred *optional = [OMDeferred deferred];

[[[[API sharedInstance] doTwo] fulfilled:^(id result) {
    [optional fulfil:result];
}] failed:^(NSError *error) {
    [optional fulfil:nil];
}];

OMPromise *all = [OMPromise all:@[
    [[API sharedInstance] doOne],
    optional.promise
]];

[[all fulfilled:^(id result) {

    GTLog(@"%@", result);

}] failed:^(NSError *error) {

    GTErr(@"%@", error);

}];

But is there a more elegant way?

Support cancellation

It would be nice to allow some sort of cancellation. Meaning that the user of the promise can indicate that he is no longer interested in the result of the promise. Therefore the underlying deferred could interrupt the ongoing operation, if possible.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.