如何在 Kotlin 中编写一系列 Promise?

JP *_*ura 4 android kotlin kotlinx.coroutines

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

例如,JavaScript 中的序列 promise 写为:

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();
Run Code Online (Sandbox Code Playgroud)

每个函数还返回一个带有异步处理结果的 Promise,该结果将被紧随其后的 Promise解决/拒绝。

我知道如何使用RxKotlin编写它,但我试图弄清楚如何使用协程库或任何其他标准功能来编写它。

Ren*_*ene 5

正如您提到的,协程是标准功能。

你必须使用的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()
}
Run Code Online (Sandbox Code Playgroud)

如果你喜欢更实用的错误处理风格,你可以这样做:

suspend fun run() {
    runCatching { charlie(bravo(alpha(42))) }
        .onFailure { println(it) }
        .onSuccess { println(it) }
}
Run Code Online (Sandbox Code Playgroud)