Code Monkey home page Code Monkey logo

promissum's People

Contributors

benlenarts avatar hermanbanken avatar mac-cain13 avatar mbernson avatar sdevos avatar tomasharkema avatar tomlokhorst 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

promissum's Issues

Support dispatching on GCD queues

Current (2015-01-08) behaviour is that every callback (from map, then and the like) happen synchronously on the same thread as where PromiseSource.resolve is called. Lets call this "synchronous dispatch".

Sometimes synchronous dispatch is the correct behaviour, but most of the time it leads to unexpected results.

Proposal: add dispatchOn

Add support to "configure" a promise to run on a provided dispatch queue. For example:

let myQueue = dispatch_queue_create("com.example.MyQueue", nil);

getSomePromise()
  .dispatchOn(myQueue)
  .map { value in
    // This is called on my queue
    return value
  }
  .then { value in
    // This is also called on my queue
    // That means we can't do UI operations! (not UI thread)
  }

The call to dispatchOn(queue: dispatch_queue_t) returns a new Promise that is correctly configured (i.e. it doesn't mutate the existing promise). This way we can also "switch" queues:

getSomePromise()
  .dispatchOn(myQueue)
  .map { value in
    // This is called on my queue
    return value
  }
  .dispatchOn(dispatch_get_main_queue())
  .then { value in
    // This runs on main thread, so we can do UI operations
  }

When nothing is configured, the main queue is chosen as a default (so users can do UI operations):

getSomePromise()
  .then { value in
    // Default: run on main thread
  }

However, if for some reason, you want to dispatch synchronously, this can be done using dispatchSync():

getSomePromise()
  .dispatchSync()
  .then { value in
    // This now runs on whatever thread `PromiseSource.resolve` was called on.
    // This can be used if the caller of `resolve` expects the side effects from `then` to have happend.
  }

Running a "sub computation" on a different queue is also possible, using the existing flatMap:

getSomePromise()
  .dispatchOn(myQueue)
  .flatMap { value in
    return Promise(value: value)
      .dispatchOn(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0))
      .map { val in
        // This runs on a high priority queue
        return val
      }
  }
  .then { value in
    // This is also called on my queue
    // That means we can't do UI operations! (not UI thread)
  }

Improve inline documentation

Explain details of the different combinators, when supplied closures are run.

In particular: Explain how flatMapResult runs on both values and errors.

Also explain when registered handlers are cleaned up.

Add custom error type

Currently (2015-04-16) Promissum only uses NSError for errors.

By changing the type Promise<T> to Promise<Value, Error> a custom error type can be provided.

This would allow for more type-safe, fine grained error handling.

Warning about Alamofire not being safe for Application Extensions

When using the Promissum/Alamofire subspec you'll get the following warning:

ld: warning: linking against a dylib which is not safe for use in application extensions: /Users/[yada-yada]-iphonesimulator/Alamofire/Alamofire.framework/Alamofire

This is because Alamofire declares NOT to be safe for use in application extensions, while Promissum declares it is:

s.pod_target_xcconfig = { 'APPLICATION_EXTENSION_API_ONLY' => 'YES' }

`.mapError()` not working?

We are using Promissum in a legacy project that we are trying to upgrade to Swift 3, but I found some issues when doing so.

Say that I have something like:

class Api {
  // ... 
  fileprivate func requestJSON(_ path: Path) -> Promise<SuccessResponse<AnyObject>, ApiError> {
    let url = path.url(baseUrl)
    return manager
      .request(url)
      .responseJSONPromise()
      .mapError(self.errorTransformer)
  }
  
  // MARK: Error helpers
  
  fileprivate func errorTransformer(_ error: ErrorResponse) -> ApiError {
    return .networkingError(error.result as NSError)
  }
    
  // ...
}

Where ApiError is:

import Foundation
import Statham

public enum ApiError : Error {
  case notFound
  case networkingError(NSError)
  case jsonDecodingError(Error)
}

extension ApiError: CustomStringConvertible {
  public var description: String {
    switch self {
    case .notFound: return NSLocalizedString("Not Found", comment: "Api Error: resource not found")
    case .networkingError(let error): return error.localizedDescription
    case .jsonDecodingError(let error):
      #if DEBUG
        if let error = error as? JsonDecodeError {
          print(error.fullDescription)
        }
      #endif
      return NSLocalizedString("Server error", comment: "Api Error: Server error")
    }
  }
}

The problem comes when using .mapError(), where the compiler complains about "Argument passed to call that takes no arguments". Digging in the github, I can see that indeed there is this following method mapError() that does not take any arguments and that is a new addition since the 0.5.0 version.

I can see however the right method here, but it seems that extension is sort of overriding the right one? Or am I missing something important here?

Reduce stack size when debugging

Suggested by @sdevos. See if it's possible to reduce the size of the call stack when debugging code related to promises.

It might be necessary to manually inline a lot of code, making the internals of Promissum a bit uglier. Let's investigate to see if this is worth the trouble.

Make it possible to switch deinit warning message off by default

This message: PromiseSource.deinit: WARNING: Unresolved PromiseSource deallocated, maybe retain this object? appears in our test suite log often, which makes the test results difficult to read. The warning is useful in a production context, but not while testing. It would be nice to be able to disable the warning globally. Although we could disable the warning on an instance-by-instance basis, we would prefer to not need to change the construction of promises throughout the codebase.

Improve Readme

Include at least:

  • Some general explanation of what promises are
  • Particular details of Promissum (map, flatMap, then, and PromiseSource)
  • Installation instructions

Missing combinator: whenAllResult

public func whenAllResult<Value, Error>(promises: [Promise<Value, Error>]) -> Promise<[Result<Value, Error>], NoError> {
  let source = PromiseSource<[Result<Value, Error>], NoError>()
  var results = promises.map { $0.result }
  var remaining = promises.count

  if remaining == 0 {
    source.resolve([])
  }

  for (ix, promise) in promises.enumerate() {

    promise
      .finallyResult { result in
        results[ix] = result
        remaining = remaining - 1

        if remaining == 0 {
          source.resolve(results.map { $0! })
        }
    }
  }

  return source.promise
}

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.