使用Scala RX中的FRP管理资源

zig*_*tar 5 scala frp

我正在scala rx申请一个申请.我有一个反应变量持有File(这是一个PDF文件).我正在使用库将此pdf文件中的页面呈现到屏幕上.现在我正在使用的PDF库给了我一个对象(让我们称之为Doc),我可以使用它来渲染单个页面.但是,为了从Doc对象呈现页面,Doc必须打开该对象(因此必须获取资源).

现在我正在为我正在重新渲染的每个页面加载pdf文件(创建一个新Doc对象并在渲染单个页面后关闭它).这使得页面的呈现起作用(给定文件和页码,返回图像).

有没有办法坚持开放的资源在FRP的变化关闭它scala rx,特别是?如何处理这种非常常见的情况?

ter*_*ret 0

您可以简单地包含 Doc 对象。所以而不是渲染

def render(file: File, pageNumber: Int): Image =  // blah blah blah
Run Code Online (Sandbox Code Playgroud)

将其更改为:

def open(file: File): (Int => Image) = {
  val doc = // call your library to read file
  (x: Int) => doc.getPage(x)
}
Run Code Online (Sandbox Code Playgroud)

然后将函数 open 返回到您正在响应的任何页面更改信号。

编辑:哦,我明白了,所以你是说你希望它在 file:File 信号更改为不同文件时关闭文件。在这种情况下你应该能够做这样的事情:

def pageGetterRx(file: Rx[File]): Rx[Int => Image] = {
  val doc: Var[Doc] = Var(null)
  val o = file.foreach { f =>
    Option(doc()).foreach(_.close)
    doc() = PdfLib.read(f)  // or however you do the reading
  }
  Rx {
    (x: Int) => doc().getPage(x)
  }
}
Run Code Online (Sandbox Code Playgroud)

编辑 2:为了澄清,如果您在 FRP 上强加“组装函数网络阶段/在某些信号阶段运行网络”区别,则上述函数将仅被调用一次;在组装阶段。换句话说,pageGetterRx(一个糟糕的名字,我完全知道)不参与 FR 方式,而是返回一个 lambda 信号,每个 lambda 信号都关闭一个特定文件并从中返回页面。