RxJava-将delaySubscription与withLatestFrom一起使用

时间:2019-09-22 13:28:36

标签: android rx-java rx-java2

很难解释我的问题,这就是为什么我将尝试用一个更简单的例子来解释。 (我还将在括号中加上我的案子,以阐明为什么我需要解决此问题)

    val interval =
        Observable.interval(1, TimeUnit.SECONDS)

    val delayedRandomNumber =
        Observable.fromCallable {
            val randomNumber = Random().nextInt()
            Log.d("LogTag", "random number = $randomNumber")
            randomNumber
        }.delay(5000, TimeUnit.MILLISECONDS)

    interval
        .observeOn(Schedulers.io())
        .filter { it != 0L }
        .delaySubscription<Int>(delayedRandomNumber)
        .withLatestFrom(delayedRandomNumber, BiFunction<Long, Int, String> { second, randomNumber ->
            "$randomNumber mod $second = ${randomNumber%second}"
        })
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe {
            Log.d("LogTag", it)
        }

时间间隔-很明显,它每秒发出一次值(在我的情况下是从EditText发出的用户输入)

delayedRandomNumber -这会生成一个随机数,并在5秒钟后发出。我只需要生成一次,但是现在我不知道如何生成(在我的情况下,这是来自服务器的城市的json树)

delaySubscription -我正在使用此运算符来等待随机数。如果不使用它,我将不会获得第二个值1,2,3的值(在我的情况下,我需要从第一个字母开始,因为它是基于树的数据-我有这样的约束)

withLatestFrom -我正在使用此运算符来避免每次生成随机数(就我而言,我不想每次输入更改时都从服务器获取数据)

所以我需要同时使用 delaySubscription withLatestFrom 。但这是通过两次生成随机数(在我的情况下是两次加载数据)中造成的问题

运行此代码时,日志如下所示:

random number = -1870536123
random number = -1834197628
-1870536123 mod 1 = 0
-1870536123 mod 2 = -1
-1870536123 mod 3 = 0
-1870536123 mod 4 = -3
-1870536123 mod 5 = -3
-1870536123 mod 6 = -3

如您所见,随机数生成了两次。

还有其他方法可以解决此问题吗?如果是,怎么办?

1 个答案:

答案 0 :(得分:2)

这是因为ng g c view1 --project=yourNewApp cold observable或单播。每个订阅都有自己的生产者(在您的情况下,Observable.fromCallable内部的随机数生成是生产者)。

为避免此问题,您可以使用share运算符多播delayedRandomNumber

delayedRandomNumber

输出

    val delayedRandomNumber =
        Observable.fromCallable {
            val randomNumber = Random().nextInt()
            Log.d("LogTag", "random number = $randomNumber")
            randomNumber
        }.delay(5000, TimeUnit.MILLISECONDS)
         .share()

也请阅读blog by Dan Lew,因为我发现多播可观察的问题很有帮助。