【问题标题】:Access CoroutineContext element via Key class通过 Key 类访问 CoroutineContext 元素
【发布时间】:2020-12-19 18:26:19
【问题描述】:

在 Ktor 中,我希望实现某种方式来引用 coroutineContext 中的键值对,而无需在方法参数中拖动对对象的引用。基于https://proandroiddev.com/demystifying-coroutinecontext-1ce5b68407ad我写了我的参考类:

class MyElement(override val key: CoroutineContext.Key<*>, val value: String) : CoroutineContext.Element
class MyKey: CoroutineContext.Key<MyElement>

... // 内部路由:

val key: CoroutineContext.Key<MyElement> = MyKey()
val ele = MyElement(key, "myJWT")
withContext(coroutineContext + ele) {
    val notNullEle : MyElement = coroutineContext[ele.key] as MyElement // not null
    logger.info(notNullEle.value) // "myJWT"
    val shouldNotBeNullEle = coroutineContext[MyKey()]// NULL!
}
val shouldBeNull = coroutineContext[ele.key] // is and should be null
val shouldBeNull2 = coroutineContext[MyKey()] // is and should also be null

当我将 ele.key 发送到 coroutineContext[ele.key] 时,我得到了正确的元素,但是当我发送 MyKey 的新实例时,我得到 null,因此 MyElement 的实例清楚地映射到键的实例。但是,这对我的目的并不适用,因为我希望使用 MyKey 类来获取 MyElement 的实例,因为我希望能够例如在服务层中获取 HttpClient 中的值而无需一路传递ele.key。有可能吗?

我的问题与How to make request-bound data globally available in Ktor? 基本相同,遗憾的是没有得到答复。

【问题讨论】:

  • 考虑一个具有Map 属性的CoroutineContext.Element,而不是尝试将每个键值对打包到它们自己的元素中。 (CoroutineContext.Elements 的设计并不是为了在一个上下文中包含很多。)

标签: kotlin kotlin-coroutines ktor


【解决方案1】:

如您链接的文章中所述,您可以将CoroutineContext 视为以CoroutineContext.Key 作为其键的Map

鉴于此前提,您遇到的问题很明确,ele.key != MyKey() 或键在定义上不等效,因此它们不会在上下文 Map 中返回相同的条目。

这就是为什么大多数CoroutineContext.Key 实现都是object 的原因,因为它实现了基于对象单例的equals 方法。您需要同时使用object 或正确实现equalshashCode

【讨论】:

    猜你喜欢
    • 2017-12-16
    • 2015-06-06
    • 1970-01-01
    • 1970-01-01
    • 2017-05-17
    • 1970-01-01
    • 2023-02-14
    • 2016-08-09
    • 2019-05-18
    相关资源
    最近更新 更多