如何在不使用 scala 隐式的情况下传递执行上下文以进行理解?

How can I pass execution context in for comprehension whithout using implicit in scala?

我有一个代码用于理解 运行 数据库查询:

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) 

totalFeeNoticeAmountFromDBlistOfRestrictedFundFromDB 都是已经启动的 Future 类型。

有没有路过这里 <-(?:ExecutionContext) ?

你可以重写

val res = for {
  totalFeeNoticeAmount <- totalFeeNoticeAmountFromDB
  listOfRestrictedFund <- listOfRestrictedFundFromDB
} yield (totalFeeNoticeAmount, listOfRestrictedFund)

作为

val res = totalFeeNoticeAmountFromDB.flatMap(totalFeeNoticeAmount =>
  listOfRestrictedFundFromDB.map(listOfRestrictedFund =>
    (totalFeeNoticeAmount, listOfRestrictedFund)
  )
)

例如,如果 totalFeeNoticeAmountFromDBlistOfRestrictedFundFromDBFuture,那么您可以显式传递隐式 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)

也许考虑 scala-async which has gained experimental compiler support -Xasync 在 Scala 2.13.3 中,其中以下 for-comprehension

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。

另一个 hacky 选项可能是 better-monadic-for,它支持在 for-comprehensions 中定义隐式

val ec: ExecutionContext = ???
(for {
  implicit0(ec: ExecutionContext) <- Future.successful(ec)
  a <- Future(41)(ec)
  b <- Future(1)(ec)
} yield {
  a + b
})(ec)

我认为解决这个问题最简单的方法就是创建一个辅助函数。

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)
}

那样当你需要它的时候你可以这样调用它:foo(ec = myExplicitExecutionContext)