与斯卡拉的期货混淆

时间:2015-10-15 17:57:15

标签: scala async-await future

我想为REST API创建一个非阻塞的Web服务。

此Web服务应返回如下所示的Json:

[{"elementA": [{"id:" "1", "Type": "a", "elements":[{"idOfElement":"3", "typeOfElement": "4", "otherData": "Some"}]}]}] 

我正在使用Async / Await,但问题是每个函数在未来解析之前都返回它,因此元素的集合将返回空。

以下是一个函数的示例:

val sensorPositionParameters: InputSensorPositionRequestValues = {
  parseSensorPositionInput(sensorRequest)
}
var sensorPositionRequestDeviceSequence: LinearSeq[SensorPositionRequestDevice] = {
  LinearSeq[SensorPositionRequestDevice]()
}
async {
  try {
    sensorPositionParameters.deviceMacAddress.foreach(
      // TODO: Remove the blocking result
      deviceMacAddress => Await.result(async {
        val sensorHubs = await(
          SensorHubRepository.sensorHubsFromDeviceMacAddress(deviceMacAddress)
        )
        val processedSensorHubs = await(processSensorHubs(sensorHubs))
        sensorPositionRequestDeviceSequence = sensorPositionRequestDeviceSequence :+
          SensorPositionRequestDevice(deviceMacAddress, processedSensorHubs)
      }, Duration.Inf)
    )
    parseSensorPositionOutput(sensorPositionRequestDeviceSequence)
  }
  catch {
    case ex: Exception => s"$unexpectedSensorPositionErrorPrefix ${ex.getMessage}"
    case _: Throwable => s"$unexpectedSensorPositionError"
  }
}

正如您所看到的,我在代码中添加了Await.result,但我想尽量避免阻塞。

抱歉我的英语不好,如果我的问题不清楚,我会编辑它以改善它。

感谢您的关注

1 个答案:

答案 0 :(得分:0)

首先,你应该在foreach循环中链接所有调用:

val futures = sensorPositionParameters.deviceMacAddress.map (deviceMacAddress=>
  for(
    sensorHubs <-   SensorHubRepository.sensorHubsFromDeviceMacAddress(deviceMacAddress);
    processedSensorHubs <- processSensorHubs(sensorHubs)
  ) yield processedSensorHubs
)

这将为您提供期货清单。然后,您需要使用Future.sequence(期货)将此期货列表转换为列表的未来。

当然,这不是一个完整的解决方案。我希望你现在得到一个如何避免使用等待功能的提示