3

使用 Futures 和 Promises 进行延迟初始化是否合适,而不是使用 Option var 或一些可变变量?

您可以创建一个封装承诺的工厂类:

class IntFactory{
  val intPromise = Promise[Int]
  def create () : Future[Int] = intPromise.future
  def init (data : String) : Unit = intPromise success data.length
}

然后演员或其他一些类可以像这样使用它:

class MyActor(factory : IntFactory) extends Actor{
  val future_int = factory.create()

  def receive = {
    case (msg : String) => factory.init(msg) // Now the promise is fulfilled  
  }
}

做这样的事情有什么问题吗?以演员为例可能并不理想,因为我认为演员有更好的选择(成为或 FSM)。我目前正在考虑将它与非演员类一起使用。在某些事件发生之前,一些实例变量什么都不是。我正在考虑这样做,而不是使用 var Option 并将其设置为 None。如果这很糟糕,还有哪些其他选择?

编辑:

我想到了这可能更有用的情况。如果我有多个需要初始化的东西,并且我有一些我想在完成后执行的异步操作:

class MyActor(factory1 : IntFactory, factory2 : IntFactory) extends Actor{
  val future_int1 = factory1.create()
  val future_int2 = factory2.create()

  for{
    x <- future_int1
    y <- future_int2
  } // Do some stuff when both are complete

  def receive = {
    case "first" => factory1.init("first") 
    case "second" => factory2.init("second") 
  }
}

这样我就不必在每次得到另一块时检查哪些是无的。

更多编辑:

我在原始问题中未能指定的一些附加信息:

  1. 初始化对象所需的数据将异步传入。

  2. 初始化需要传递给 init 函数的数据。我编辑了我的示例代码,现在就是这种情况。

  3. 我没有使用 Akka。我认为 Akka 有助于整理一个快速示例,并认为有经验的 Akka 人员可以提供有用的反馈。

4

2 回答 2

2

是的,这肯定是比使用可变变量(无论是否Option)更好的方法。正如@ PatrykĆwieklazy val所建议的那样,如果您可以随时初始化状态而不是等待外部事件并且不需要异步执行,那么使用会更好。

于 2013-11-04T08:57:59.137 回答
0

从你的判断来看IntFactory,你真的不需要data字符串(它没有在任何地方使用),所以我认为基本情况可以这样重写:

class Foo {
  lazy val first = {
    Thread.sleep(2000) // Some computation, initialization etc.
    25
  }
  lazy val second = {
    Thread.sleep(1000) // Some computation, initialization etc.
    11
  }
  def receive(s : String) = s match {
    case "first" => first
    case "second" => second
    case _ => -1
  }
}

现在,假设您这样做:

val foo = new Foo()
println(foo.receive("first"))  // waiting for 2 seconds, initializing
println(foo.receive("first"))  // returns immediately
println(foo.receive("second")) // waiting for 1 second, initializing

现在两者firstsecond最多可以初始化一次

您不能将参数传递给lazy vals,因此如果data字符串对初始化很重要,那么您最好使用带有记忆化 (IMO) 的工厂方法。

于 2013-11-04T13:15:58.233 回答