首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >复制enqueue()方法

复制enqueue()方法
EN

Stack Overflow用户
提问于 2019-11-13 19:34:21
回答 2查看 171关注 0票数 1

我有以下方法,它简单地以以太同步或ASYNC方式获取数据:

代码语言:javascript
复制
enum class CallType { SYNC, ASYNC }

suspend fun get( url: String, callType : CallType, mock : String? = null, callback: Callback? ): Response?
{
    var response : okhttp3.Response ?= null

    val request = Request.Builder()
        .url( url )
        .build()

    val call = client.newCall( request )

    if( mock != null )
    {
        // this works fine for SYNC, but how to make it work with ASYNC callback?
        delay( 1000 )
        return okhttp3.Response.Builder().body(
            ResponseBody.create( "application/json".toMediaType(), mock )
        ).build()
    }

    if( callType == CallType.ASYNC && callback != null )
        call.enqueue( callback )
    else
        response = call.execute()

    return response
}

我希望能够模拟/覆盖响应。通过同步方式,我可以很好地做到这一点,因为我只需构造并返回一个假的out 3.响应,就像下面的代码片段一样,代码执行停止了,一切都进行得很好:

代码语言:javascript
复制
    if( mock != null )
    {
        delay( 1000 )
        return okhttp3.Response.Builder().body(
            ResponseBody.create( "application/json".toMediaType(), mock )
        ).build()
    }

问题是,我希望能够对ASYNC调用做同样的事情,但我不知道从这里到哪里。我基本上是在复制enqueue()方法,这样在经过一些延迟之后,我的回调就会被触发(这个回调被传递给get()方法),而我的假的okhttp3.Response通过回调而不是返回返回。对于如何做到这一点,有什么建议吗?谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-11-18 10:10:01

您正在将不同的概念与实现混合在一起。异步应该使用CoroutineContext而不是参数来控制。像这样,您将始终返回一个非空值。另外,明智的做法是隐藏实现细节(这里是OkHttp),而不是公开它。

您可以使用suspendCoroutine将OkHttp与couroutine连接起来。

代码语言:javascript
复制
suspend fun get(
    url: String,
    mock : String? = null
) = if(mock != null) {
    delay( 1000 )
    Response.Builder().body(
        ResponseBody.create(
            "application/json".toMediaType()
            mock
        )
    ).build()
} else suspendCoroutine { continuation ->
    client.newCall(
        Request.Builder()
            .url(url)
            .build()
    ).enqueue(
        object : Callback {
            override fun onFailure(call: Call, e: IOException) =
                continuation.resumeWithException(e)
            override fun onResponse(call: Call, response: Response) =
                continuation.resume(response)
        }
    )
}

要同步访问它,只需使用

代码语言:javascript
复制
runBlocking { get(url, mock) }

如果您确实需要提供您自己的Callable,您可以很容易地将它委托给它。但是,您也必须创建一个呼叫,即使您在嘲弄响应时不需要它。

票数 1
EN

Stack Overflow用户

发布于 2019-11-17 16:01:56

一种简单的方法是以同步方式调用回调:

代码语言:javascript
复制
if (mock != null) {
  val response = ... // prepare mock response here
  callback.onResponse(response)
}

因此,甚至在get函数完成之前就会调用回调。

如果要实现响应实际上是异步交付的,则需要从额外的协同线执行模拟传递。

代码语言:javascript
复制
if (mock != null) {
   GlobalScope.launch {
      val response = ... // prepare mock response here
      delay(1000)
      callback.onResponse(response)
   }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58844346

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档