Kotlin 在发射器响应后按顺序运行多个任务

Kotlin 在发射器响应后按顺序运行多个任务,kotlin,rx-java,Kotlin,Rx Java,我正在尝试为硬件设备创建一个通信控制器,它总是以一定的延迟响应。如果我只请求一个值,我可以创建一个单,并在.subscribe{…}中进行最终转换 但是当我请求多个值时,我需要确保第二个请求发生在第一个请求完全关闭之后 这是我可以用RxJava做的吗,例如?或者我应该自己创建一个队列,并使用队列手动处理事件序列 无论如何,我们都在使用RxJava(我显然是新手),当然,出于这个目的使用它也会很好。但这是一个好的用例吗 编辑: 我可以使用的代码,但不够通用: hardware.write(byte

我正在尝试为硬件设备创建一个通信控制器,它总是以一定的延迟响应。如果我只请求一个值,我可以创建一个
,并在
.subscribe{…}
中进行最终转换

但是当我请求多个值时,我需要确保第二个请求发生在第一个请求完全关闭之后

这是我可以用RxJava做的吗,例如?或者我应该自己创建一个队列,并使用队列手动处理事件序列

无论如何,我们都在使用RxJava(我显然是新手),当然,出于这个目的使用它也会很好。但这是一个好的用例吗

编辑:

我可以使用的代码,但不够通用:

hardware.write(byteArray)
    .subscribe(
        {
            hardware.receiveResult().take(1)
                .doFinally { /* dispose code */ }
                .subscribe(
                    { /* onSuccess */ }
                    { /* onError */ }
                .let { disposable = it }
        },
        { /* onError */ }
    )    
队列中下一个请求的所有代码都可以放入内部
onSuccess
,然后放入下一个
onSuccess
。这将按顺序执行,但不够通用。任何其他发出请求的类都会破坏我的序列


我正在寻找一种在硬件通信控制器类中自动建立队列的解决方案。

很长时间过去了,项目开发了,我们很久以前就得到了解决方案。现在我想在这里分享一下:

fun writeSequential(data1: ByteArray, data2: ByteArray) {
    disposable = hardwareWrite(data1)
        .zipWith(hardwareWrite(data2))
        .subscribe(
            {
                /* handle results.
                  it.first will be the first response,
                  it.second the second. */
            },
            { /* handle error */ }
        )

    compositeDisposable.add(disposable)
}

fun hardwareWrite(data: ByteArray): Disposable {
    var emitter: SingleEmitter<ByteArray>? = null
    var single = Single.create<ByteArray> { emitter = it }

    return hardware.write(data)
        .subscribe(
            { hardwareRead(emitter) },
            { /* onError */ }
        ))
}

fun hardwareRead(emitter: SingleEmitter<ByteArray>): Disposable {
    return hardware.receiveResult()
        .take(1)
        .timeout( /* your timeout */ )
        .single( /* default value */ )
        .doFinally( /* cleanup queue */ )
        .subscribe(
            { emitter.onSuccess(it) }
            { emitter.onError(it) }
        )
}
fun writeSequential(数据1:ByteArray,数据2:ByteArray){
一次性=硬件写入(数据1)
.zipWith(硬件写入(数据2))
.订阅(
{
/*处理结果。
这是第一个反应,
这是第二次*/
},
{/*句柄错误*/}
)
compositeDisposable.add(一次性)
}
有趣的硬件写入(数据:ByteArray):一次性{
变量发射器:SingleEmitter?=null
var single=single.create{emitter=it}
返回硬件。写入(数据)
.订阅(
{硬件头(发射器)},
{/*onError*/}
))
}
有趣的硬件设备(发射器:单发射器):一次性{
返回硬件。receiveResult()
.采取(1)
.timeout(/*您的超时*/)
.single(/*默认值*/)
.doFinally(/*清理队列*/)
.订阅(
{emitter.onSuccess(it)}
{emitter.onError(it)}
)
}
解决方案并不完美,现在我看到中间部分对一次性结果没有任何作用

同样在out的例子中,它有点复杂,因为hardwareWrite不会立即启动,而是排队。通过这种方式,我们可以确保按顺序访问硬件,并且不会混淆结果


尽管如此,我还是希望这能帮助那些正在寻找解决方案的人,他们可能是kotlin和/或RxJava之类的新手(就像我在项目开始时一样)。

很长一段时间过去了,项目开发了,我们很久以前就得到了解决方案。现在我想在这里分享一下:

fun writeSequential(data1: ByteArray, data2: ByteArray) {
    disposable = hardwareWrite(data1)
        .zipWith(hardwareWrite(data2))
        .subscribe(
            {
                /* handle results.
                  it.first will be the first response,
                  it.second the second. */
            },
            { /* handle error */ }
        )

    compositeDisposable.add(disposable)
}

fun hardwareWrite(data: ByteArray): Disposable {
    var emitter: SingleEmitter<ByteArray>? = null
    var single = Single.create<ByteArray> { emitter = it }

    return hardware.write(data)
        .subscribe(
            { hardwareRead(emitter) },
            { /* onError */ }
        ))
}

fun hardwareRead(emitter: SingleEmitter<ByteArray>): Disposable {
    return hardware.receiveResult()
        .take(1)
        .timeout( /* your timeout */ )
        .single( /* default value */ )
        .doFinally( /* cleanup queue */ )
        .subscribe(
            { emitter.onSuccess(it) }
            { emitter.onError(it) }
        )
}
fun writeSequential(数据1:ByteArray,数据2:ByteArray){
一次性=硬件写入(数据1)
.zipWith(硬件写入(数据2))
.订阅(
{
/*处理结果。
这是第一个反应,
这是第二次*/
},
{/*句柄错误*/}
)
compositeDisposable.add(一次性)
}
有趣的硬件写入(数据:ByteArray):一次性{
变量发射器:SingleEmitter?=null
var single=single.create{emitter=it}
返回硬件。写入(数据)
.订阅(
{硬件头(发射器)},
{/*onError*/}
))
}
有趣的硬件设备(发射器:单发射器):一次性{
返回硬件。receiveResult()
.采取(1)
.timeout(/*您的超时*/)
.single(/*默认值*/)
.doFinally(/*清理队列*/)
.订阅(
{emitter.onSuccess(it)}
{emitter.onError(it)}
)
}
解决方案并不完美,现在我看到中间部分对一次性结果没有任何作用

同样在out的例子中,它有点复杂,因为hardwareWrite不会立即启动,而是排队。通过这种方式,我们可以确保按顺序访问硬件,并且不会混淆结果


尽管如此,我还是希望这可以帮助那些正在寻找解决方案的人,他们可能是kotlin和/或RxJava之类的新手(就像我在项目开始时一样)。

您是否需要提出第二个请求,与第一个请求相同,但仅在第一个请求关闭之后。或者您需要在第二个请求中使用第一个请求的结果?结果是独立的。但是,如果请求在前一个请求得到响应之前到达,那么硬件就会变得混乱。因此,它必须在执行
.subscribe(onSuccess
块之后执行。您可以共享一些您已经拥有的代码吗,或者应该如何共享?必须在同一线程上运行这些代码,如Schedulers.single()?然后一个项目的发射将阻塞线程,因此第二个项目只有在第一个项目被处理后才会到达。@BorisSafonov我添加了一些代码。您是否需要发出第二个请求,与第一个请求相同,但仅在第一个请求关闭后。或者您需要在第二个请求中使用第一个请求的结果?结果是独立的。但是如果请求在前一个响应之前到达,则硬件会变得混乱。因此,它必须在执行
.subscribe(onSuccess
块之后。是否可以共享一些您已经拥有的代码,或者应该如何或多或少地在同一线程上运行这些代码,如调度器。single()?然后一个项目的发射将阻塞线程,因此只有在第一个项目被处理后,第二个项目才会到达。@BorisSafonov I添加了一些代码。