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

[Idea] Add `FlattenStrategy.throttle` #549

Open
inamiy opened this issue Nov 10, 2017 · 5 comments

Comments

@inamiy
Copy link
Contributor

commented Nov 10, 2017

Related to FlattenStrategy.race implemented in #233, I thought it will be useful to have FlattenStrategy.raceContinuous (or case race(continuous: Bool)) FlattenStrategy.throttleas well.

In theory, this will work similar to .flatMap(.merge) { someAPIAction.apply($0) } but omitting Action which may sometimes become too verbose to declare (if we aren't interested in enabledIf, isExecuting, etc).

Use case

Example: Loading next API after scrollView reached bottom

let reachedBottom = Signal<(), NoError>.pipe()  // let's say, scrollView triggers this
let nextPageProperty = MutableProperty<Int>(0) // state

let responses = reachedBottom.output
    .withLatest(from: nextPageProperty.producer)
    .flatMap(.throttle) { nextPage -> SignalProducer<Response, NoError>in
        return loadNext(nextPage) // some API request
            .flatMapError { _ in .empty } // ignore network error
    }

nextPageProperty <~ responses.map { $0.nextPage }

responses
    .observeCompleted { print("done!") }

// main

reachedBottom.input.send(value: ())
// 1st loadNext progressing...
reachedBottom.input.send(value: ())
// 1st loadNext still progressing, no 2nd loadNext

wait(1) // wait until API finished
// 1st loadNext completed

reachedBottom.input.send(value: ())
// 2nd loadNext progressing...
reachedBottom.input.send(value: ())
// 2nd loadNext still progressing, no 3rd loadNext

reachedBottom.input.sendCompleted()
// 2nd loadNext still progressing, no print "done" yet

wait(1) // wait until API finished
// 2nd loadNext completed, prints "done"
@inamiy

This comment has been minimized.

Copy link
Contributor Author

commented Nov 10, 2017

Sorry, actually this is not race but rather FlattenStrategy.first a.k.a. flatMapFirst.

@andersio

This comment has been minimized.

Copy link
Member

commented Nov 10, 2017

It seems throttle is the best fit verb for this, just that it throttles by progress rather than a minimum time interval.

@inamiy

This comment has been minimized.

Copy link
Contributor Author

commented Nov 11, 2017

Right, case throttle sounds better name 😄

@inamiy inamiy changed the title [Idea] Add `FlattenStrategy.raceContinuous` [Idea] Add `FlattenStrategy.throttle` Nov 11, 2017

@mdiep

This comment has been minimized.

Copy link
Contributor

commented Nov 12, 2017

This seems conceptually similar to concat except that the queue/buffer isn't infinite.

Maybe this?

public static func queue(limit: UInt) -> FlattenStrategy {  }
@inamiy

This comment has been minimized.

Copy link
Contributor Author

commented Nov 13, 2017

@mdiep
Interesting!
Since static let concat = FlattenStrategy(kind: .concurrent(limit: 1)), it should probably be improved like this:

public static func concurrent(limit: UInt, queueCount: UInt) -> FlattenStrategy

so that more flexible flattening e.g. limit = 10 && queueCount = 5 will be possible (though I don't know who will ever use this!).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.