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

Closed
inamiy opened this issue Nov 10, 2017 · 6 comments
Closed

[Idea] Add FlattenStrategy.throttle #549

inamiy opened this issue Nov 10, 2017 · 6 comments

Comments

@inamiy
Copy link
Contributor

inamiy 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
Copy link
Contributor Author

inamiy commented Nov 10, 2017

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

@andersio
Copy link
Member

andersio 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
Copy link
Contributor Author

inamiy 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
Copy link
Contributor

mdiep 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
Copy link
Contributor Author

inamiy 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!).

@RuiAAPeres
Copy link
Member

Hello. 👋 Thanks for opening this issue. Due to inactivity, we will soft close the issue. If you feel that it should remain open, please let us know. 😄

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

4 participants