Scala 完成请求后如何关闭STTP后端?

Scala 完成请求后如何关闭STTP后端?,scala,monix,sttp,Scala,Monix,Sttp,我目前正在使用Monix后端学习和使用STTP。我的主要任务是在我的所有请求(每个请求都是一个任务)处理完毕后关闭后端 我创建了与我的问题相似的示例/模拟代码(据我所知,我的问题更一般,而不是特定于我的代码): 我的fetch(api调用生成器)函数如下所示: def fetch(uri: Uri, auth: String)(implicit backend: SttpBackend[Task, Observable[ByteBuffer], WebSocketHandler]

我目前正在使用Monix后端学习和使用STTP。我的主要任务是在我的所有请求(每个请求都是一个任务)处理完毕后关闭后端

我创建了与我的问题相似的示例/模拟代码(据我所知,我的问题更一般,而不是特定于我的代码):

我的fetch(api调用生成器)函数如下所示:

  def fetch(uri: Uri, auth: String)(implicit
      backend: SttpBackend[Task, Observable[ByteBuffer], WebSocketHandler]
  ) = {
    println(uri)
    val task = basicRequest
      .get(uri)
      .header("accept", "application/json")
      .header("Authorization", auth)
      .response(asString)
      .send()

    task
  }

由于我的主任务包含其他任务(稍后需要处理),因此我需要找到一种从外部关闭Monix后端的替代方法。在我使用了
列表[Task[Response[orther[String,String]]]]
中的请求后,是否有一种干净的方法关闭后端?

问题来自这样一个事实,即在sttp后端打开时,您正在计算要执行的任务列表-
列表[Task[Response[ory[orry[String,String]]]]]]]
,但你不是在管理他们。因此,我们需要在后端关闭之前对运行这些任务进行排序

这里要做的关键是创建一个任务的单一描述,在后端仍然打开时运行所有这些请求

一旦您计算了
数据
(它本身就是一个任务-一个计算的描述-当运行时,它会产生一个任务列表-也就是计算的描述),我们需要将其转换为一个单一的、非嵌套的
任务
。这可以通过多种方式完成(例如,使用简单的排序),但在您的情况下,这将使用
可观察的

AsyncHttpClientMonixBackend().flatMap{implicit backend=>
val ID:Task[List[Int]=Task{(1到3).toList}
val f:String=>Task[Response[任一[String,String]]]=(i:String)=>fetch(uri“$i”,“”)
val数据:任务[列表[任务[响应]或[字符串,字符串]]]]]=
ids映射(u映射(=>f(“https://heloooo.free.beeceptor.com/my/api/path")))
val活动=可观察
.fromTask(数据)
.flatMap{listoffetchs=>
可观察的。从可观察的(列表项)
}
.节气门(3秒,1)
.mapEval(身份)
.完成的
活动.保证(
backend.close()
)
}
首先请注意,
Observable.fromTask(…)
位于最外层的
flatMap
内部,因此在后端仍然打开时创建。我们创建可观察对象,对其进行限制等等,然后出现一个关键事实:一旦我们有了限制流,我们就使用
mapEval
评估每个项目(每个项目都是
任务[…]
-如何发送一个http请求的描述)。我们得到一个
流[String,String]
,这是请求的结果

最后,我们使用
.completedL
(丢弃结果)将流转换为
任务
(等待整个流完成)

最后一个任务是关闭后端。如上所述,将发生的副作用的最终顺序是:

  • 打开后端
  • 创建任务列表(
    数据
  • 创建一个流,该流限制由
    data
  • 评估流中的每个项目(发送请求)
  • 关闭后端
  •   def fetch(uri: Uri, auth: String)(implicit
          backend: SttpBackend[Task, Observable[ByteBuffer], WebSocketHandler]
      ) = {
        println(uri)
        val task = basicRequest
          .get(uri)
          .header("accept", "application/json")
          .header("Authorization", auth)
          .response(asString)
          .send()
    
        task
      }