web-dev-qa-db-ja.com

値を返すコトリンコルーチン

戻り値を持つコルーチンメソッドを作成したいです。

例えば)

fun funA() = async(CommonPool) {
    return 1
}

fun funB() = async(CommonPool) {
    return 2
}

fun sum() {
    launch {
        val total = funA().await() + funB().await()
    }
}

Sumメソッドで合計を返したい場合、どうすればよいですか?

お気に入り、

fun sum(): Int {
    launch {
        val total = funA().await() + funB().await()
    }   

    return total
}
10
Expert wanna be

正確にIntを返すには、コルーチンの世界から抜け出す必要があり、それがrunBlockingの目的です。

fun sum(): Int = runBlocking {
    funA().await() + funB().await()
}

コルーチンガイドの ブロッキングおよびノンブロッキングワールドのブリッジング 、および サスペンド機能の作成 を参照してくださいsuminsideコルーチンを使用します。

16
Alexey Romanov

それを達成する別の方法を追加します。

fun sum(): Int {
    var sum: Int = 0
    runBlocking {
        val jobA = async { funA() }
        val jobB = async { funB() }
        runBlocking{
           sum = jobA.await() + jobB.await()
        }
    }
    return sum
}

suspend fun funA(): Int {
    return 1
}

suspend fun funB(): Int {
    return 2
}
4
Sahil Chhabra

この質問に答えるのは遅いかもしれませんが、うまくいけば誰かがそれを役に立つと思うでしょう。以下のコードスニペットは、3つの値A + B + Cの合計を計算します。各値は、独自のバックグラウンドスレッドで並行して個別に計算され、その後、すべての中間結果が1つの最終結果に統合され、メインスレッドに返されて画面に表示されます。

したがって、最終値を計算するのに5秒かかり(10秒= 2 + 3 + 5ではない)、結果は明らかに6であり、非ブロッキングです。メインスレッドはsum()の実行が完了していない間に他のイベントを処理できます。

suspend fun sum(scheduler: ThreadPoolExecutor): Int = coroutineScope {

    withContext(scheduler.asCoroutineDispatcher()) {
        val a = async { funA() }
        val b = async { funB() }
        val c = async { funC() }

        a.await() + b.await() + c.await()
    }
}

fun funA(): Int {
    Thread.sleep(2000L)
    return 1
}

fun funB(): Int {
    Thread.sleep(3000L)
    return 2
}

fun funC(): Int {
    Thread.sleep(5000L)
    return 3
}

class MainActivity : AppCompatActivity(), View.OnClickListener {
    private val tripletsPool = ThreadPoolExecutor(3, 3, 5L, TimeUnit.SECONDS, LinkedBlockingQueue())

   ...

    override fun onClick(view: View?) {
        if (view == null) {
            return
        }

        when (view.id) {
            R.id.calculate -> {
                GlobalScope.launch(Dispatchers.Main, CoroutineStart.DEFAULT) {
                    progressBar.visibility = View.VISIBLE
                    result.setText("${sum(tripletsPool)}")
                    progressBar.visibility = View.GONE
                }
            }
        }
    }
}
2
Aleksei Mulin

私はあなたの仕事を編集し、funAとfunBをサスペンド関数に変更し、合計演算子の関数を作成し、この関数のメイン関数を呼び出します:

suspend fun funA(): Int{
    return 1
}

suspend fun funB(): Int {
    return 2
}
fun sum() = runBlocking{
    val resultSum = async { funA.await() + funB.await() }
    return resultSum
}

fun main() = runBlocking{
    val result = async { sum() }
    println("Your result: ${result.await()}")
}

それが役立つことを願っています

0
Cevin Ways

これは、Roomデータベースから電話番号を削除しようとしたときにブール値を返すための方法です。達成しようとしているものに同じパターンを使用できます。私のビューモデルでは:

private var parentJob = Job()
private val coroutineContext: CoroutineContext get() = parentJob + Dispatchers.Main
private val scope = CoroutineScope(coroutineContext)

suspend fun removePhoneNumber(emailSets: EmailSets, personDetails: PersonDetails) : Boolean  {
    var successReturn = false
    scope.async(Dispatchers.IO) {
        val success = async {removePhoneNumbersAsync(emailSets,personDetails)}
        successReturn = success.await()

    }
    return successReturn
}

fun removePhoneNumbersAsync(emailSets: EmailSets, personDetails : PersonDetails):Boolean {
    var success = false
    try {
        val emailAddressContact = EmailAddressContact(emailSets.databaseId, personDetails.id, personDetails.active)
        repository.deleteEmailAddressContact(emailAddressContact)
        val contact = Contact(personDetails.id, personDetails.personName, personDetails.personPhoneNumber, 0)  
        repository.deleteContact(contact)
        success = true
    } catch (exception: Exception) {
        Timber.e(exception)
    }
    return success
}

私の活動では:

runBlocking {
    if (v.tag != null) {
            val personDetails = v.tag as PersonDetails
            val success  = viewModel.removePhoneNumber(emailSets,personDetails)
            if (success) {
                val parentView = v.parent as View
                (parentView as? TableRow)?.visibility = View.GONE
                val parentViewTable = parentView.parent as ViewGroup
                (parentViewTable as? TableLayout)
                parentViewTable.removeView(parentView)
            }
     }

}
0
Kristy Welsh