简体   繁体   English

使用属性作为 Kotlin 协程的访问器

[英]Use property as accessor for Kotlin Coroutine

Kotlin Coroutines question... struggling w/ using a property instead of a function being the accessor for an asynchronous call. Kotlin 协程问题...挣扎着使用属性而不是 function 作为异步调用的访问器。

Background is that I am trying to use the FusedLocationProviderClient with the kotlinx-coroutines-play-services library in order to use the .await() method on the Task instead of adding callbacks...背景是我正在尝试将FusedLocationProviderClientkotlinx-coroutines-play-services库一起使用,以便在Task上使用.await()方法而不是添加回调......

Currently having a property getter kick out to a suspend function, but not sure on how to launch the coroutine properly in order to avoid the目前有一个属性获取器被踢出以暂停 function,但不确定如何正确启动协程以避免

required Unit found XYZ找到所需的单位 XYZ

error...错误...

 val lastUserLatLng: LatLng?
        get() {
            val location = lastUserLocation
            return if (location != null) {
                LatLng(location.latitude, location.longitude)
            } else {
                null
            }
        }

    val lastUserLocation: Location?
        get() {
            GlobalScope.launch {
                return@launch getLastUserLocationAsync()  <--- ERROR HERE
            }
        }

    private suspend fun getLastUserLocationAsync() : Location? = withContext(Dispatchers.Main) {
        return@withContext if (enabled) fusedLocationClient.lastLocation.await() else null
    }

Any thoughts on how to handle this?关于如何处理这个问题的任何想法?

Properties can't be asynchronous.属性不能是异步的。 In general you should not synchronize asynchronous calls.一般来说,您不应该同步异步调用。 You'd have to return a Deferred and call await() on it when you need a value.当您需要一个值时,您必须返回一个Deferred并在其上调用await()

val lastUserLatLng: Deferredd<LatLng?>
    get() = GlobalScope.async {
        lastUserLocation.await()?.run {
            LatLng(latitude, longitude)
        }
    }

val lastUserLocation: Deferred<Location?>
    get() = GlobalScope.async {
        getLastUserLocationAsync()
    }

private suspend fun getLastUserLocationAsync() : Location? = withContext(Dispatchers.Main) {
    return@withContext if (enabled) fusedLocationClient.lastLocation.await() else null
}

But technically it's possible, though you should not do it.但从技术上讲,这是可能的,尽管你不应该这样做。 runBlocking() blocks until a value is available and returns it. runBlocking()阻塞直到一个值可用并返回它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM