将隐式 ExecutionContext 传递给包含的对象/调用的方法

2023-11-24

我正在使用 Scala 2.10 futures 创建一个异步库。库的构造函数采用一系列实现特定特征的用户定义对象,然后库类上的方法将一些数据逐一发送到用户定义的对象中。我希望用户提供ExecutionContext用于设置主实例时的异步操作,然后根据需要将该上下文传递到用户定义的对象中。简化(伪?)代码:

case class Response(thing: String)

class LibraryObject(stack: Seq[Processor])(implicit context: ExecutionContext) {
  def entryPoint(data: String): Future[Response] = {
    val response = Future(Response(""))
    stack.foldLeft(response) { (resp, proc) => proc.process(data, resp) }
  }
}

trait Processor {
  def process(data: String, resp: Future[Response]): Future[Response]
}

它可能会这样使用:

class ThingProcessor extends Processor {
  override def process(data: String, response: Future[Response]) = {
    response map { _.copy(thing = "THE THING") }
  }
}

class PassThroughProcessor extends Processor {
  override def process(request: Request, response: Future[Response]) = {
    response
  }
}

object TheApp extends App {
  import ExecutionContext.Implicits.global

  val stack = List(
    new ThingProcessor,
    new PassThroughProcessor
  )
  val libObj = new LibraryObject(stack)

  val futureResponse = libObj.entryPoint("http://some/url")

  // ...
}

我收到编译错误ThingProcessor:

找不到隐式 ExecutionContext,要么自己需要一个,要么导入ExecutionContext.Implicits.global

我的问题是,我如何隐式提供ExecutionContext that LibraryObject必须是用户定义的对象(ThingProcessor and PassThroughProcessor)或他们的方法,而不会让用户(将编写类)担心它 - 也就是说,我更希望用户这样做not必须输入:

class MyFirstProcessor(implicit context: ExecutionContext)

or

override def process(...)(implicit context: ExecutionContext) = { ... }

隐式作用域包括基类的伴生对象和类型参数。

或者,library.submit(new library.Processor { def process() ... })。

这可行,但不是我的第一个想法,这是更聪明的:

import concurrent._
import concurrent.duration._

class Library(implicit xc: ExecutionContext = ExecutionContext.global) {
  trait Processor {
    implicit val myxc: ExecutionContext = xc
    def process(i: Future[Int]): Future[Int]
  }

  def submit(p: Processor) = p process future(7)
}

object Test extends App {
  val library = new Library
  val p = new library.Processor {
    def process(i: Future[Int]) = for (x <- i) yield 2 * x
  }
  val res = library submit p
  val z = Await result (res, 10.seconds)
  Console println z
}

Update:

import concurrent._
import concurrent.duration._
import java.util.concurrent.Executors

class Library()(implicit xc: ExecutionContext = ExecutionContext.global) {
  trait Processor {
    implicit val myxc: ExecutionContext = xc
    def process(i: Future[Int]): Future[Int]
  }

  def submit(p: Processor) = p process future(7)
}

object ctx {
  val xc = ExecutionContext fromExecutorService Executors.newSingleThreadExecutor
}
object library1 extends Library
object library2 extends Library()(ctx.xc)
object p extends library1.Processor {
  def process(i: Future[Int]) = for (x <- i) yield 2 * x
}
object q extends library2.Processor {
  def process(i: Future[Int]) = for (x <- i) yield 3 * x
}

object Test extends App {
  val res = library1 submit p
  //val oops = library2 submit p
  //val oops = library1 submit q
  val z = Await result (res, 10.seconds)
  Console println z
  Console println (Await result (library2 submit q, 10.seconds))
  ctx.xc.shutdownNow()
}

这并不难:

class Library(implicit xc: ExecutionContext = ExecutionContext.global) {

  def submit(p: Processor): Future[Int] = p dueProcess future(7)
}
trait Processor {
  implicit var myxc: ExecutionContext = _
  def dueProcess(i: Future[Int])(implicit xc: ExecutionContext) = {
    myxc = xc
    process(i)
  }
  protected def process(i: Future[Int]): Future[Int]
}

object ctx {
  val xc = ExecutionContext fromExecutorService Executors.newSingleThreadExecutor
}
object Test extends App {
  def db() = Console println (new Throwable().getStackTrace mkString ("TRACE [\n  ", "\n  ", "\n]"))
  val library = new Library()(ctx.xc)
  val p = new Processor {
    protected def process(i: Future[Int]) = for (x <- i) yield { db(); 2 * x }
  }
  val res = library submit p
  val z = Await result (res, 10.seconds)
  Console println z
  ctx.xc.shutdownNow()
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将隐式 ExecutionContext 传递给包含的对象/调用的方法 的相关文章

随机推荐

  • “shutdown -y”到底是做什么的? [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我在之后尝试了一些随机参数shutdown当我偶然发现 PowerShell 2 0 中的命令时shutdown y 所有这一切seems要做的就是注销用户 如果使用任何其他随机字母
  • python 中的泛型/模板?

    python 如何处理泛型 模板类型场景 假设我想创建一个外部文件 BinaryTree py 并让它处理二叉树 但适用于任何数据类型 所以我可以将自定义对象的类型传递给它 并拥有该对象的二叉树 这是如何在 python 中完成的 其他答案
  • 更改图钉颜色 MKMapView

    我以这种方式向地图添加注释 MyAnnotation annotationPoint2 MyAnnotation alloc init annotationPoint2 coordinate anyLocation annotationPo
  • 在运行时创建继承抽象类并实现接口的类型

    我们的架构广泛使用存储库模式 我们为大多数存储库提供了一个抽象基类 它实现了一些常见的功能 例如获取 加载 列表等 这个基类有一个对应的接口IRepository 它定义了抽象类的公共方法 大多数实体都有对应的存储库接口 例如Foo 实体有
  • .htaccess 将根目录重定向到index.php

    我需要重定向自http example com to http example com index php 用这个 DirectoryIndex index php
  • 使用 GCC 查找无法访问的函数(“死代码”)

    我正在寻找一种在 非常 大型 C 项目中查找静态无法访问的函数的方法 我曾尝试使用 doxygen 和此处建议的其他静态分析工具 但似乎该项目太复杂 他们无法处理 最后我决定使用 GCC 工具 g gprof gcov 等 是最安全的选择
  • Flutter 中的元素是什么?

    我很难理解 Flutter 中的元素是什么 来自文档 树中特定位置的小部件的实例化 我想现在我必须问 那棵树是什么 起初 我以为树指的是小部件的状态 但 StatelessWidget 也有 createElement 所以情况似乎并非如此
  • 使用较小的默认对齐方式重载 new 运算符

    C 17 引入过度对齐数据的动态内存分配 除了现有的std max align t 基本对齐 它补充说 STDCPP DEFAULT NEW ALIGNMENT 运算符 new 保证的最小对齐 通过 MSVC2017 64 位编译 这些常量
  • 如何使用 Apache POI 读取具有日期的 Excel 单元格?

    我正在使用 Apache POI 3 6 我想读取一个具有如下日期的 Excel 文件8 23 1991 switch cell getCellType case HSSFCell CELL TYPE NUMERIC value NUMER
  • 将 Quartz.Net 与 UI 相结合

    我一直在从事 MVC3 项目 我刚刚在我的应用程序中使用 Quartz Net 创建了示例电子邮件发送作业 这次 我需要在我的MVC3项目中构建一个作业调度系统 该场景完全基于 UI 这意味着 系统用户必须通过 UI 输入调度频率 例如定义
  • Petri网绘图和代码生成

    是否有任何软件可以绘制 Petri 网并从那里生成任何源代码 源代码可以采用任何已知的编程语言 稍微不太理想的选择是以某种开放格式 例如 XML 或任何其他数据语言 在基于文本的文件中输出仅包含 Petri 网图描述的文件 然后我可以自己编
  • 向累积图添加 95% 置信限

    我想使用 R 添加一条抛物线 表示 95 的置信极限到这个抛硬币图 x lt sample c 1 1 60000 replace TRUE plot ts cumsum x ylim c 250 250 Here is an exampl
  • AttributeError:模块“os”没有属性“uname”

    当我做 gt gt gt import os gt gt gt os uname 我收到一个属性错误 如下所示 Traceback most recent call last File
  • 如何处理python请求中的401(未经授权)

    我想要做的是从站点获取 如果该请求返回 401 则重做我的身份验证摆动 可能已过时 并重试 但我不想尝试第三次 因为那将是我的身份验证摇摆不定的凭证 有没有人有一个很好的方法来做到这一点 并且不涉及丑陋的代码 最好是在 python req
  • Python:Xlib——如何升起(置顶)窗口?

    我尝试过使用 win configure stack mode X TopIf win set input focus X RevertToParent X CurrentTime 然而 即使我的窗口管理器上没有任何焦点丢失预防措施 这也不
  • 是否可以在ios 9中获取wifi信号强度

    我想检查 WIFI 信号强度 以便在 WIFI 信号弱时显示某种消息 我发现在 iOS 8 及更早版本中这是不可能的 iOS 9 中可以获取 wifi 信号强度吗 如果答案是肯定的那么如何 是的 在 iOS 9 中是可能的 查看一下NE热点
  • Oreo 版本问题不支持此图像的编辑

    Oreo 版本问题中的此图像不支持编辑 此图像不支持编辑 当从 Oreo 版本移动设备中的图库中选择图像时 会显示此 Toast 我已经问过这个问题了 但没有人回复我 请检查我的代码并尽快恢复 这是我的代码 Override public
  • 使用 pyinotify 监视文件创建,但等待它完全写入磁盘

    我正在使用 pyinotify 来监视文件夹中何时创建文件 当创建某些文件时 我想移动它们 问题是 一旦创建文件 显然 我的程序就会尝试移动它 甚至在它完全写入磁盘之前 有没有办法让 pyinotify 等到文件完全写入磁盘后再通知我它已创
  • CSS 在 Chrome 中不起作用

    我正在处理的网站的此页面未加载 CSS http www thesanfordcenter net sanford center 它只发生在 Chrome 中 但不是缓存问题 因为同样的问题也发生在另一台计算机上的 Chrome 中 并且我
  • 将隐式 ExecutionContext 传递给包含的对象/调用的方法

    我正在使用 Scala 2 10 futures 创建一个异步库 库的构造函数采用一系列实现特定特征的用户定义对象 然后库类上的方法将一些数据逐一发送到用户定义的对象中 我希望用户提供ExecutionContext用于设置主实例时的异步操