scala - 有没有办法在未来链中执行副作用,而不改变价值传播
问题描述
我有一个未来链,它获取资源,使用它来检索一些数据,然后改变该数据并返回结果(仍在未来)。
我想在返回未来链之前释放资源,但不必插入更接近的样板代码(即将中间结果放入某个变量,然后将其作为结果返回链的其余部分)。
我正在寻找类似的东西:
.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
解决方案
你可以这样做:
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)
推荐阅读
- java - 无法反序列化 @JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
- autofac - 为什么调用 AutoFake.Provide() 会清除已使用 A.CallTo() 配置的假货?
- bluetooth - 恢复出厂设置 HC-06
- javascript - 已解决:D3 更改单个节点的属性
- javascript - 包含等于“=”且没有引号的字符串转换为 JSON
- matlab - 如何在单个半对数图上绘制特征值 λc、λd 作为其索引的函数
- java - 使用 Java BufferedImage 的图像过滤器:如何更改所有像素的颜色,直到它们收敛到总灰度图像
- ios - UITableView 的高度其内容与自动布局但限制 UITableView 高度
- javascript - 使用 javascript 查找最小值和最大值
- vba - Visual Basic 中的 lg 函数