首页 文章

我如何在Kotlin写一系列的承诺?

提问于
浏览
2

是否可以使用 only Kotlin编写一系列promise(或任务)?

例如,JavaScript中的序列承诺写为:

const SLEEP_INTERVAL_IN_MILLISECONDS = 200;

const alpha = function alpha (number) {
    return new Promise(function (resolve, reject) {
        const fulfill = function() {
            return resolve(number + 1);
        };

        return setTimeout(fulfill, SLEEP_INTERVAL_IN_MILLISECONDS);
    });
};

const bravo = function bravo (number) {
    return new Promise(function (resolve, reject) {
        const fulfill = function() {
            return resolve(Math.ceil(1000*Math.random()) + number);
        };
        return setTimeout(fulfill, SLEEP_INTERVAL_IN_MILLISECONDS);
    });
};

const charlie = function charlie (number) {
    return new Promise(function (resolve, reject) {
        return (number%2 == 0) ? reject(number) : resolve(number);
    });
};

function run() {
    return Promise.resolve(42)
        .then(alpha)
        .then(bravo)
        .then(charlie)
        .then((number) => {
            console.log('success: ' + number)
        })
        .catch((error) => {
            console.log('error: ' + error);
        });
}

run();

每个函数also returns a Promise具有异步处理结果,由紧随的后续承诺解析/拒绝 .

我知道如何使用RxKotlin编写这个,但我试图弄清楚如何使用coroutines library或任何其他标准功能来编写它 .

1 回答

  • 2

    正如您所提到的,coroutines是标准功能 .

    如果函数将被暂停,则必须使用 suspend 关键字,例如IO,或者如果你调用另一个 suspend 函数,例如 delay .

    可以使用正常的 try-catch 语句完成错误处理 .

    import kotlinx.coroutines.delay
    import java.lang.Exception
    import kotlin.math.ceil
    
    const val SLEEP_INTERVAL_IN_MILLISECONDS = 200
    
    suspend fun alpha(number: Int): Int {
        delay(SLEEP_INTERVAL_IN_MILLISECONDS)
        return number + 1
    }
    
    suspend fun bravo(number: Int): Int {
        delay(SLEEP_INTERVAL_IN_MILLISECONDS)
        return ceil(1000 * Math.random() + number).toInt()
    }
    
    fun charlie(number: Int): Int =
        number.takeIf { it % 2 == 0 } ?: throw IllegalStateException(number.toString())
    
    suspend fun run() {
        try {
            val result = charlie(bravo(alpha(42)))
            println(result)
        } catch (e: Exception) {
            println(e)
        }
    }
    
    suspend fun main() {
        run()
    }
    

    如果您喜欢更具功能性的错误处理方式,可以使用以下方法:

    suspend fun run() {
        runCatching { charlie(bravo(alpha(42))) }
            .onFailure { println(it) }
            .onSuccess { println(it) }
    }
    

相关问题