Android 使用RxJava的工作队列

Android 使用RxJava的工作队列,android,multithreading,rx-java,rx-android,Android,Multithreading,Rx Java,Rx Android,我想使用RxJava创建工作队列:我有一个线程在做一些工作,我想保证在完成/失败当前作业之前不会执行其他作业 我的解决方案只是阻止可观察到的结果并等待结果: fun foo() : Observable<Foo> { return Observable.unsafeCreate { subscriber -> handlerThread.post { val answer = object.performSomeJob(whate

我想使用RxJava创建工作队列:我有一个线程在做一些工作,我想保证在完成/失败当前作业之前不会执行其他作业

我的解决方案只是阻止可观察到的结果并等待结果:

fun foo() : Observable<Foo> {
    return Observable.unsafeCreate { subscriber ->
        handlerThread.post {
            val answer = object.performSomeJob(whatever)
                    .flatMap { object.performAnotherJob(whatever) }
                    .flatMap { object.performLastJob(whatever) }
                    .blockingFirst()
            subscriber.onNext(answer)
            subscriber.onComplete()
        }
    }
}
fun foo():可观察{
返回Observable.unsafeCreate{subscriber->
handlerThread.post{
val answer=object.performSomeJob(无论什么)
.flatMap{object.performAnotherJob(无论什么)}
.flatMap{object.performLastJob(无论什么)}
.blockingFirst()
subscriber.onNext(应答)
subscriber.onComplete()
}
}
}
您可能会争辩说,没有必要使用RxJava,因为一切都是同步的。对于这种特殊的方法是这样的,但是:

  • 我想避免“回调地狱”:有三种方法,每种方法都接受回调,我使用RxJava来链接它们
  • 我在调用方方法中进一步使用Rx

  • 我知道
    阻塞
    通常被认为是一种反模式,因此我能做得更好吗?

    您可以使用
    concat
    在某些线程上按顺序执行工作:

    fun foo(): Observable<Foo> {
        return performSomeJob(whatever)
            .concatMap { performAnotherJob(whatever) }
            .concatMap { performLastJob(whatever) }
            .subscribeOn(Schedulers.newThread())
    }
    
    fun foo():可观察{
    返回performSomeJob(无论什么)
    .concatMap{performAnotherJob(无论什么)}
    .concatMap{performLastJob(无论什么)}
    .subscribeOn(Schedulers.newThread())
    }
    
    您可以使用
    concat
    在某些线程上按顺序执行工作:

    fun foo(): Observable<Foo> {
        return performSomeJob(whatever)
            .concatMap { performAnotherJob(whatever) }
            .concatMap { performLastJob(whatever) }
            .subscribeOn(Schedulers.newThread())
    }
    
    fun foo():可观察{
    返回performSomeJob(无论什么)
    .concatMap{performAnotherJob(无论什么)}
    .concatMap{performLastJob(无论什么)}
    .subscribeOn(Schedulers.newThread())
    }
    
    您可以将所有工作安排在一个单线程上,例如

    @非空 公共静态调度器 对于需要在同一后台线程上执行强顺序的工作,返回一个默认的、共享的、单线程支持的调度程序实例

    fun foo():可观察=
    Observable.fromCallable{object.performSomeJob(无论什么)}
    .subscribeOn(Schedulers.single())
    .observeOn(Schedulers.single())
    .flatMap{object.performAnotherJob(无论什么)}
    .flatMap{object.performLastJob(无论什么)}
    
    您可以将所有工作安排在一个单线程上,例如

    @非空 公共静态调度器 对于需要在同一后台线程上执行强顺序的工作,返回一个默认的、共享的、单线程支持的调度程序实例

    fun foo():可观察=
    Observable.fromCallable{object.performSomeJob(无论什么)}
    .subscribeOn(Schedulers.single())
    .observeOn(Schedulers.single())
    .flatMap{object.performAnotherJob(无论什么)}
    .flatMap{object.performLastJob(无论什么)}
    
    如何确保调用线程调用performAnotherJob Observable?可能是performAnotherJob在另一个线程上订阅。此外,flatMap的maxConcurrency应该是1。@HansWurst假设
    performAnotherJob
    performLastJob
    不更改线程本身,它们将在
    Schedulers.single()上观察到。如果他们做更复杂的事情,那是在他们的控制之下,而不是我们的控制之下。无论
    maxConcurrency
    允许多少订阅者,一次只能在
    Scheduler.observable()
    上运行一个任务。是的,作业可能会更改线程并从另一个线程调用observable。不幸的是,我无法控制该代码。@ephemient,您的示例将无法运行。请查看此代码:。如果添加.flatMap(integer->create(integer),1),则它将起作用。@HansWurst它在示例中起作用,但仍然失败,因为多个
    foo()
    仍可能同时发生多个任务。如果作业切换线程,您对此无能为力。如何确保调用线程时会调用performAnotherJob Observable?可能是performAnotherJob在另一个线程上订阅。此外,flatMap的maxConcurrency应该是1。@HansWurst假设
    performAnotherJob
    performLastJob
    不更改线程本身,它们将在
    Schedulers.single()上观察到。如果他们做更复杂的事情,那是在他们的控制之下,而不是我们的控制之下。无论
    maxConcurrency
    允许多少订阅者,一次只能在
    Scheduler.observable()
    上运行一个任务。是的,作业可能会更改线程并从另一个线程调用observable。不幸的是,我无法控制该代码。@ephemient,您的示例将无法运行。请查看此代码:。如果添加.flatMap(integer->create(integer),1),则它将起作用。@HansWurst它在示例中起作用,但仍然失败,因为多个
    foo()
    仍可能同时发生多个任务。如果作业切换线程,您将无能为力。
    fun foo(): Observable<Foo> =
        Observable.fromCallable { object.performSomeJob(whatever) }
            .subscribeOn(Schedulers.single())
            .observeOn(Schedulers.single())
            .flatMap { object.performAnotherJob(whatever) }
            .flatMap { object.performLastJob(whatever) }