首页 > 解决方案 > 有没有办法在未来链中执行副作用,而不改变价值传播

问题描述

我有一个未来链,它获取资源,使用它来检索一些数据,然后改变该数据并返回结果(仍在未来)。

我想在返回未来链之前释放资源,但不必插入更接近的样板代码(即将中间结果放入某个变量,然后将其作为结果返回链的其余部分)。

我正在寻找类似的东西:

.getResource() //returns future
   .flatMap(resource => resource.getUsageResult()) //returns future
    .FUNCTION_I_NEED(resource.free()) 
    //executes for failures and successes, doesn't change propagated exceptions or values
   .flatMap(usageResult => mutate(usageResult)) //returns future

标签: scalafuture

解决方案


你可以这样做:

getResource()
  .flatMap(resource => {
    resource.getUsageResult()
      .map(result => {
        // .map makes sure the usage result is done
        // do your side effect here
        yourSideEffectOn(resource)
        // return the result again so you can do something with it
        result
      })
  })
  .flatMap(usageResult => mutate(usageResult))

您应该能够通过使用理解来简化这一点:

for {
  resource <- getResource()
  usageResult <- getUsageResult(resource)
} yield {
  yourSideEffectOn(resource) // will not wait if it returns a future
  mutate(usageResult)
}

如果我没记错的话,这应该也可以:

for {
  resource <- getResource()
  usageResult <- getUsageResult(resource)
  _ = yourSideEffectOn(resource) // will not wait if it returns a future
} yield mutate(usageResult)

如果您也想等待副作用完成(如果失败则中断),您也可以 flatMap 副作用:

for {
  resource <- getResource()
  usageResult <- getUsageResult(resource)
  _ <- yourSideEffectOn(resource) // will wait for side effect to finish
} yield mutate(usageResult)

推荐阅读