Scala - 使用Iterator循环并使用状态检查器

时间:2018-03-28 12:51:23

标签: scala while-loop iterator

首先,我是Scala的新手。我有以下(工作)Scala方法,必须等待15秒才能完成记录。通常,在7秒后,记录完成。所以,我把一个迭代器放到最多15秒,如果记录完成则停止(我不知道如何停止迭代而不是掉线)。如果没有完成,它应该睡1秒。问题是我必须提供方法checkIfRecordIsComplete作为参数,因为我可能将此wait方法与其他布尔函数一起使用。我怎么能用wait方法...让我们说checkIfOtherIsComplete?谢谢!

def checkIfRecordIsComplete(record: Record) = {
    println("record.state="+record.state)
    if(record.state.contains(Constants.RecordStatusComplete))
      true
    else
      false
}

def checkIfOtherIsComplete(other: Other) = {
    println("other.state="+other.state)
    if(other.state.contains(Constants.OtherStatusComplete))
      true
    else
      false
}

def wait(recordId: RecordId, maxW: Int): Unit = {
    val it = Iterator.iterate(1){_+1}.take(maxW)
    while(it.hasNext) {
      val recordList = getRecord(recordId)
      recordList.records.foreach {
        record => {
          if(!checkIfRecordIsComplete(record)){
            Thread.sleep(1000)
            it.next()
          }
          else
            it.drop(maxW)
        }
      }
    }
}

........................
wait(recordId, 15)

1 个答案:

答案 0 :(得分:3)

您需要找到一种为RecordOther提供常用功能的类型。在这种情况下,可能是两者都实现的trait。例如:

trait Completable {

  def isComplete: Boolean

}

现在,RecordOther都应该扩展它:

trait Record extends Completable {

  // ...

  override def isComplete: Boolean = this.state.contains(Constants.RecordStatusComplete)

}

trait Other extends Completable {

  // ...

  override def isComplete: Boolean = this.state.contains(Constants.OtherStatusComplete)

}

wait函数应略微更改,以便能够访问Completable的序列(列表)。实际上,由于检查逻辑现在位于RecordOther内,因此不再需要像checkIfOtherIsComplete这样的专用函数:

// returns the Completable to be checked for completion.
// replaces the former getRecord
private def getItems(recordId: RecordId): Seq[Completable] = ???

def wait(recordId: RecordId, maxW: Int): Unit = {
  val it = Iterator.iterate(1){_+1}.take(maxW)
  while(it.hasNext) {
    getItems(recordId).foreach{
      item => if (item.isComplete) {
        Thread.sleep(1000)
        it.next()
      } else {
        it.drop(maxW)
      }
    }
  }
}
顺便说一下,我对使用这种Iterator方法进行此类检查的已实施解决方案的可靠性表示怀疑。但是既然它有效,那么你的情况可能就好了。如果您有兴趣,我们可以继续讨论。

更新

实现等待序列的另一种方法可能是使用scala.concurrent.*包中的标准Scala功能。

我们可以使用Future并等待其完成。例如:

import scala.concurrent.duration.Duration
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.{Await, Future}

def wait2(recordId: RecordId, maxW: Int): Unit = {
  val waitForAllComplete = Future {
    while(!getItems(recordId).forall(_.isComplete)) {
      Thread.sleep(1000)
    }
  }
  Await.ready(waitForAllComplete, Duration(maxW, "second"))
}

现在,如果序列在maxW秒后未完成,则会抛出TimeoutException。如果您需要确保列表中的所有项目都符合预期状态并处理意外情况,这可能会有所帮助。

结束更新