使用Kotlin协程实现涉及状态机的握手过程

时间:2020-05-27 21:10:10

标签: kotlin kotlin-coroutines

我是Kotlin的新手,需要实现执行握手过程的代码。这意味着有输入和输出数据以及状态机。示例:

class Handshake {
    fun readData(data: List<Byte>): Outcome {
        if (currentState == State.STATE_1) {
            if (inspectState1Data(data) == Result.INVALID) {
                return Outcome.NEED_MORE_DATA // 
            } else {
                currentState = State.STATE_2
                return Outcome.CALL_AGAIN
            }
        } else if (currentState == State.STATE_2) {
            when (inspectState2Data(data)) {
                Result.REQUIRES_EXTRA_INFO -> return Outcome.PROVIDE_EXTRA_INFO
                Result.INVALID -> return Outcome.FAILURE
            }
        }
    }
}

readData()函数必须被重复调用。如果返回Outcome.CALL_AGAIN,则会再次调用它。如果返回Outcome.PROVIDE_EXTRA_INFO,则必须首先以某种方式将额外的信息传递给Handshake类,等等。

在此示例中,该函数简短易懂,但是一旦涉及更多状态,并且状态变得更加复杂,此代码很快就会变得混乱。

我想将其更改为:

suspend fun processHandshake(): Boolean {
    // State 1

    while (true) {
        // Loop until we get valid data
        val data: List<Byte> = suspendUntilResumedWithData() // How would this look like in Kotlin?
        if (inspectState1Data(data) != Result.INVALID)
            break
    }

    // State 2

    while (true) {
        // Loop until we are done. If during the process we
        // require extra info, request one. In this state,
        // however, receiving invalid data is not recoverable,
        // we need to exit with failure instead.
        val data: List<Byte> = suspendUntilResumedWithData()
        when (inspectState2Data(data)) {
            Result.REQUIRES_EXTRA_INFO -> {
                val extraInfo: ExtraInfo = suspendUntilResumedWithExtraInfo()
                processExtraInfo(extraInfo)
            }
            Result.INVALID -> return false // Return false to indicate failure
        }
    }

    return true // Success - return true
}

对我来说,第二种形式更具可读性,并且当然与Kotlin协程基础结构配合得很好,尤其是在诸如取消工作等细节方面。与另一种形式相比,此代码的外观更具顺序性。

但是,我不清楚suspendUntilResumedWithData()suspendUntilResumedWithExtraInfo()的样子。我确实知道Continuation对象,但是不确定在这里如何正确使用它们。有什么建议吗?

0 个答案:

没有答案