Как задержать в асинхронной функции, которая возвращает Отложено <T> - PullRequest
0 голосов
/ 07 февраля 2019

У меня ниже кодлин котлин сопрограммы.doWorkAsync - нормальная (не приостановленная) функция, которая возвращает Deferred<Int>.

import kotlinx.coroutines.*

fun main() = runBlocking {
    val result = doWorkAsync("Hello ")
}

fun doWorkAsync(msg: String): Deferred<Int>  = async {
    log("$msg - Working")
    delay(500)
    log("$msg - Work Done")
    return@async 42
}

fun log(msg: String ) {
    println("$msg in ${ Thread.currentThread().name }")
}

Я не знаю, как использовать delay в функции doWorkAsync.

Iиспользую котлин сопрограммы версия kotlinx-coroutines-core:1.1.1.

1 Ответ

0 голосов
/ 07 февраля 2019

Вам необходимо указать область действия:

fun doWorkAsync(msg: String) = GlobalScope.async {
    log("$msg - Working")
    delay(500)
    log("$msg - Work Done")
    return@async 42
}

Таким образом, внутри вашей лямбды у вас будет CoroutineScope.

Примечание. Поскольку вы используете тело выражения,вам не нужно явно указывать тип возврата Deferred<Int>.Это можно сделать вывод.


Более гибкое решение с использованием приостановленной функции

Но есть еще лучший способ.Я имею в виду, что в этом контексте очевидно, что функция должна быть асинхронной.Но что, если вам нужна функция, которую можно вызывать асинхронно и последовательно?

Вот где вступают в действие функции приостановки.Вы определяете свою функцию следующим образом:

suspend fun doWork(): Int {
    // ...
    delay(500)
    // ...
    return 42
}

Затем вы можете решить на call-site, как вы хотите ее использовать:

val d: Deferred<Int> = GlobalScope.async { doWork() } // asnyc
val i: Int = runBlocking { doWork() } // sequential
...