rxjava delay:如何从列表中发出的每个项目获得可变延迟?

时间:2016-08-18 07:55:46

标签: java rx-java

我希望从可观察列表中发出的每个项目之间的自定义延迟作为项目本身的函数。 假设我们有一个列表(项目,延迟):

[("item1", 2),("item2", 1),("item3", 2),("item4", 3),("item5", 2),("item6", 3)]

我希望输出类似于:

0 seconds: 
1 seconds: 
item1
2 seconds: 
item2
3 seconds: 
4 seconds: 
item3
5 seconds: 
6 seconds: 
7 seconds: 
item4
8 seconds: 
9 seconds: 
item5
10 seconds: 
11 seconds: 
12 seconds: 
item6
Completed!
13 seconds: 

我不确定如何使用延迟/计时器操作符来最好地完成此操作。通过延迟文档,但无法找到一个简单的方法。任何指针都会有所帮助。谢谢!

5 个答案:

答案 0 :(得分:13)

不需要任何花哨的东西。只需使用concatMapdelay运算符

即可
jla.concatMap(s -> Observable.just(s).delay(s.delay, TimeUnit.SECONDS))           
  .subscribe(s1 -> System.out.println(s1.name + " just came..."), 
             e -> {}, 
             () -> System.out.println("Everybody came!")); 

答案 1 :(得分:3)

您可以尝试使用.delay()的覆盖 http://reactivex.io/RxJava/javadoc/rx/Observable.html#delay(rx.functions.Func1)

看起来正是你所需要的

代码如下:

yourObservable.delay((item) -> Observable.timer(item.getDelay(), TimeUnit.SECONDS))

答案 2 :(得分:0)

我可能有一个可能的解决方案如下。虽然我觉得可以有更好的方法来实现它,但现在这种方法很有用。如果您想方设法做得更好,请建议替代/改进:

import java.util.concurrent.TimeUnit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import rx.Observable;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.functions.Func1;

public class Watchtower {
    public static void main(String[] arg) throws Exception {

        // Boilerplate for setup
        System.out.println("Welcome to Watchtower");

        class SuperHero {
            public String name;
            public long delay;

            public SuperHero(String name, int delay) {
                this.name = name;
                this.delay = (long) delay;
            }
        }

        Observable<Long> clock = Observable.interval(1, TimeUnit.SECONDS).take(14);

        clock.subscribe(tick -> System.out.println(tick + " seconds: "));

        List<SuperHero> jla = new ArrayList<>(Arrays.asList(
            new SuperHero("Bruce", 2),
            new SuperHero("Barry", 1),
            new SuperHero("Clark", 2),
            new SuperHero("Hal", 3),
            new SuperHero("Arthur", 2),
            new SuperHero("Diana", 3)
            )
        );

        // Rxjava stuff starts form here:

        Observable<SuperHero> jl = Observable.from(jla);

        final long[] cumDelay = {0};

        Observable<SuperHero> delays = jl
            .doOnNext(s -> cumDelay[0] += s.delay)
            .delay(s -> Observable.timer(cumDelay[0], TimeUnit.SECONDS));

        Observable.zip(jl, delays, (s, d) -> s)
            .doOnNext(s -> System.out.println(s.name + " just came..."))
            .doOnCompleted(() -> System.out.println("Everybody came!"))
            .subscribe();

        // Just to have program remain alive and run on normal command line
        Thread.sleep(15000);
    }
}

它产生的输出:

Welcome to Watchtower
0 seconds: 
1 seconds: 
Bruce just came...
2 seconds: 
Barry just came...
3 seconds: 
4 seconds: 
Clark just came...
5 seconds: 
6 seconds: 
7 seconds: 
Hal just came...
8 seconds: 
9 seconds: 
Arthur just came...
10 seconds: 
11 seconds: 
12 seconds: 
Diana just came...
Everybody came!
13 seconds: 

答案 3 :(得分:0)

为了延迟特定步骤,您可以使用zip并将第一个Observable.from中发出的每个项目合并为X时间间隔。

base_url('account/profile/' . hashids_encrypt($this->user->id))

这将打印

$id = hashids_decrypt($id);

此处更多实例示例https://github.com/politrons/reactive

答案 4 :(得分:0)

您还可以使Timer运营商的用户 看看这个

Integer[] arr = {1, 2, 3, 4, 5, 6, 7};
Observable.fromArray(arr)
        // timer returns a 0 value, note the nested map operator usage
        // in order to preserve original integers
        .flatMap(x -> Observable.timer(50 * x, TimeUnit.MILLISECONDS)
                    .map(y -> x))
        .timestamp()
        .subscribe(timedIntegers ->
                Log.i(TAG, "Timed String: "
                        + timedIntegers.value()
                        + " "
                        + timedIntegers.time()));