首页 > 解决方案 > 没有变量的Scala轮询循环

问题描述

轮询和 API 的 Scala 最佳实践是什么?

我正在尝试编写一个轮询 API 的 Scala 方法,检查它是否达到"SUCCESS". 在轮询时,它也可能达到像"FAILED""TIMEOUT“。

在 Java 中,我会写如下内容:

public String pollEndpoint() {
  boolean isPolling = true;
  String result = "NA";
  while (isPolling) {
    Response response = getResponse("http://myAPI.com/ready?id=1234");
    if (response.status == "FAILED") { throw new FailedException(response.reason);}
    else ... //Some other bad conditions
    else if (response.status == "SUCCESS") {
      isPolling = false;
      result = response.result; 
    }
    
    System.out.println("Current state is " + response.status); // When running, will be "RUNNING"
    Thread.sleep(1000);
  }
}

在 Scala 中,我可以这样做:

def pollEndpoint():String = {
  var isPolling = true
  var result = "NA"
  while (isPolling) {
    val response = getResponse("http://myAPI.com/ready?id=1234")
    if (response.status == "FAILED") { throw new FailedException(response.reason)}
    else ... //Some other bad conditions
    else if (response.status == "SUCCESS") {
      isPolling = false
      result = response.result 
    }
    println("Current state is " + response.status); // When running, will be "RUNNING"
    Thread.sleep(1000)  
  }
}

但是这个解决方案使用vars。

有什么好的方法可以做到这一点,只使用vals 吗?

标签: scalapollingidioms

解决方案


正如 Luis 在评论中提到的,您可以为此编写一个递归:

def pollEndpoint():String = {
  val response = getResponse("http://myAPI.com/ready?id=1234")
  println("Current state is " + response.status); // When running, will be "RUNNING"
  if (response.status == "FAILED") { ??? }
  else if (response.status == "SUCCESS") {
    response.result
  } else {
    Thread.sleep(1000)
    pollEndpoint()
  }
}

以下将模拟getResponse

var i = 5
def getResponse(str: String): Response = {
  if (i < 0) {
    Response("SUCCESS", "Great success")
  } else {
    i = i - 1
    Response("Wait", "Not done yet.")
  }
}

和电话:

pollEndpoint()

将产生:

Current state is Wait
Current state is Wait
Current state is Wait
Current state is Wait
Current state is Wait
Current state is Wait
Current state is SUCCESS

说了这么多,与其getResponse按原样定义要好得多,我们可能会这样做:

def getResponse(str: String): Future[Response]

然后简单地说:

getResponse("http://myAPI.com/ready?id=1234").map { response =>
  // Handle response
}

推荐阅读