如何 return 来自 CoroutineScope Kotlin 的 int?

How to return an int from CoroutineScope Kotlin?

我是 android 开发新手,我不知道如何从 firestore return Coroutine 中的 int...

这是我的函数代码:

    fun getSharesNumber(context: Context, name:String) = CoroutineScope(Dispatchers.IO).launch {
        try {
            var trade1:Trade
            var sharesNumber:Int
            tradesCollectionRef.document(name)
                .get()
                .addOnSuccessListener {
                        trade1 = it.toObject(Trade::class.java)!!
                            sharesNumber = trade1.shares
                    }.await()
        }catch (e:Exception){
            withContext(Dispatchers.Main){
                Toast.makeText(context,"$e",Toast.LENGTH_LONG).show()
        }
    }
}

调用此函数时请帮我return shareNumber。

你需要使用suspendCoroutine功能,看看是否能满足你的需求

    suspend fun getSharesNumber(context: Context, name:String): Int {
        return suspendCoroutine {
            try {
                var trade1:Trade
                var sharesNumber:Int
                tradesCollectionRef.document(name)
                        .get()
                        .addOnSuccessListener {
                            trade1 = it.toObject(Trade::class.java)!!
                            sharesNumber = trade1.shares

                            // return int
                            it.resume(sharesNumber)

                        }.await()
            }catch (e:Exception){
                e.printStackTrace()
                it.resumeWithException(e)
            }
        }
    }

你不能 return 从协程到非挂起函数的值,除非你使用 runBlocking,这会触发 ANR 错误并且永远不应该在 UI 代码。如果您需要 return 值,请暂停函数,并使用 withContext 而不是 CoroutineScope/launch 来 return 一个必须在 a 上计算的值后台线程。

当您使用的库已经提供 await() 暂停功能时,您不需要使用 suspendCoroutine。由于 await 是一个挂起函数,您也不必使用特定的调度程序调用它,也不需要处理回调,因此您的代码可以变成:

suspend fun getSharesNumber(context: Context, name:String): Int {
    return try {
        tradesCollectionRef.document(name).get().await()
            .toObject(Trade::class.java)?.shares
            ?: error("Document $name doesn't exist.")
    } catch (e:Exception){
        withContext(Dispatchers.Main){
            Toast.makeText(context, "$e", Toast.LENGTH_LONG).show()
        }
        -1
    }
}

在失败的情况下 returning -1。或者,您可以让它抛出异常并在更高的位置捕获它。不过,对于失败而不是抛出,return null 会更符合 Kotlin 惯用语。我没有对此进行测试,因为我不使用 Firestore,因此语法可能略有偏差。