我有一个使用理解来运行数据库查询的代码:
val totalFeeNoticeAmountFromDB = Future(/..Doing db job../)(executionContext)
val listOfRestrictedFundFromDB = Future(/..Doing db job../)(executionContext)
val res = for {
totalFeeNoticeAmount <- totalFeeNoticeAmountFromDB
listOfRestrictedFund <- listOfRestrictedFundFromDB
} yield (totalFeeNoticeAmount, listOfRestrictedFund)
我们知道要理解,我们需要传递隐式执行上下文。
但是在这种情况下,我想手动传递执行上下文。
怎么了?
已编辑:
val res = for {
totalFeeNoticeAmount <-(?:ExecutionContext) totalFeeNoticeAmountFromDB
listOfRestrictedFund <-(?:ExecutionContext) listOfRestrictedFundFromDB
} yield (totalFeeNoticeAmount, listOfRestrictedFund)
totalFeeNoticeAmountFromDB
和listOfRestrictedFundFromDB
都是已经启动的未来类型。
有什么方法可以通过这里吗
<-(?:ExecutionContext)
吗?
答案 0 :(得分:6)
也许考虑scala-async,它在Scala 2.13.3中获得了experimental compiler support -Xasync
,其中具有以下理解力
for {
a <- Future(41)
b <- Future(1)
} yield {
a + b
}
可以改写为
async {
val a = async(41)(ec)
val b = async(1)(ec)
await(a) + await(b)
}(ec)
我们可以在其中显式传递执行上下文ec
,而无需求助于flatMap / map。
另一个黑客选项可能是better-monadic-for,它支持在理解中定义隐式内容
val ec: ExecutionContext = ???
(for {
implicit0(ec: ExecutionContext) <- Future.successful(ec)
a <- Future(41)(ec)
b <- Future(1)(ec)
} yield {
a + b
})(ec)
答案 1 :(得分:3)
您可以重写
val res = for {
totalFeeNoticeAmount <- totalFeeNoticeAmountFromDB
listOfRestrictedFund <- listOfRestrictedFundFromDB
} yield (totalFeeNoticeAmount, listOfRestrictedFund)
为
val res = totalFeeNoticeAmountFromDB.flatMap(totalFeeNoticeAmount =>
listOfRestrictedFundFromDB.map(listOfRestrictedFund =>
(totalFeeNoticeAmount, listOfRestrictedFund)
)
)
例如,如果totalFeeNoticeAmountFromDB
和listOfRestrictedFundFromDB
是Future
,则可以显式传递隐式scala.concurrent.ExecutionContext.Implicits.global
val res = totalFeeNoticeAmountFromDB.flatMap(totalFeeNoticeAmount =>
listOfRestrictedFundFromDB.map(listOfRestrictedFund =>
(totalFeeNoticeAmount, listOfRestrictedFund)
)(scala.concurrent.ExecutionContext.Implicits.global)
)(scala.concurrent.ExecutionContext.Implicits.global)
答案 2 :(得分:2)
我相信解决此问题的最简单方法就是创建一个辅助功能。
library(ggplot2)
ddft=data.frame(month = c("03-2012","04-2012","05-2012","06-2012","07-2012", "08-2012","09-2012","10-2012","11-2012","12-2012","02-2013","03-2013"), frqp = c("12.3", "11.4","44.1","11.3", "1.2","15.1","35.1","12","14.1","15.1","15.1","42.1"))
lastfew <- function(x, n){
x=as.character(x)
substr(x, nchar(x)-n+1, nchar(x))
}
yearlabels=lastfew(ddft$month,4)
ddft$yearlabels=yearlabels
Frequency=as.numeric(as.character(ddft$frqp))
minima=as.integer(min(Frequency))-1
maxima=as.integer(max(Frequency))+1
step=5
ggplot(ddft, aes(x=month, y=Frequency))+
geom_point() +
theme(legend.position="none",axis.ticks.x=element_blank(),axis.title.x=element_blank(),axis.text.x=element_blank(),panel.spacing.x=unit(0.03, "lines"),panel.grid.major = element_blank())+
scale_y_continuous(breaks = seq(minima, maxima, step))+facet_wrap(~yearlabels,strip.position = "bottom",scales = "free_x")
这样,当您需要它时,您就可以这样称呼它:def foo(implicit ec: ExecutionContext): Future[(Int, Int)] = {
val totalFeeNoticeAmountFromDB = Future(/..Doing db job../)
val listOfRestrictedFundFromDB = Future(/..Doing db job../)
for {
totalFeeNoticeAmount <- totalFeeNoticeAmountFromDB
listOfRestrictedFund <- listOfRestrictedFundFromDB
} yield (totalFeeNoticeAmount, listOfRestrictedFund)
}