代码之家  ›  专栏  ›  技术社区  ›  JP Ventura

我如何在科特林写下一系列的承诺?

  •  3
  • JP Ventura  · 技术社区  · 6 年前

    有可能写一个序列 promise (或任务)使用 只有 Kotlin?

    例如,用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 回复  |  直到 6 年前
        1
  •  3
  •   Rene    6 年前

    如你所说, coroutines 是标准的功能。

    你必须使用 suspend 关键字,如果函数将被挂起,例如IO,或者如果调用另一个函数 暂停 功能,例如 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) }
    }