Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support dispatching on GCD queues #2

Closed
tomlokhorst opened this issue Jan 8, 2015 · 2 comments
Closed

Support dispatching on GCD queues #2

tomlokhorst opened this issue Jan 8, 2015 · 2 comments

Comments

@tomlokhorst
Copy link
Owner

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)
  }
@tomlokhorst
Copy link
Owner Author

For reference, this is being worked on in the feature/dispatch-method branch.

@tomlokhorst
Copy link
Owner Author

This is mostly implemented as of the 0.5.0 release. Except for .dispatchSync().

tomasharkema pushed a commit to tomasharkema/Promissum that referenced this issue Apr 21, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant