在 Scala 中处理 Futures
Messing with Futures in Scala
我想为 REST 创建一个非阻塞网络服务 API。
此 Web 服务应该 return 一个 Json 如下所示:
[{"elementA": [{"id:" "1", "Type": "a", "elements":[{"idOfElement":"3", "typeOfElement": "4", "otherData": "Some"}]}]}]
我正在使用 Async/Await,但问题是每个函数都会在 future 被解析之前完成它的 return,所以元素的集合是 returned 空的。
这是一个函数的示例:
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
,但我想尽我所能避免阻塞。
抱歉我的英语不好,如果我的问题不清楚我会编辑它来改进它。
感谢您的关注
首先,您应该将所有调用链接到您的 foreach 循环中:
val futures = sensorPositionParameters.deviceMacAddress.map (deviceMacAddress=>
for(
sensorHubs <- SensorHubRepository.sensorHubsFromDeviceMacAddress(deviceMacAddress);
processedSensorHubs <- processSensorHubs(sensorHubs)
) yield processedSensorHubs
)
这将为您提供期货清单。然后,您需要使用 Future.sequence(futures).
将此期货列表转换为列表的未来
当然,这不是一个完整的解决方案。我希望你现在得到了如何避免使用 await 函数的提示
我想为 REST 创建一个非阻塞网络服务 API。
此 Web 服务应该 return 一个 Json 如下所示:
[{"elementA": [{"id:" "1", "Type": "a", "elements":[{"idOfElement":"3", "typeOfElement": "4", "otherData": "Some"}]}]}]
我正在使用 Async/Await,但问题是每个函数都会在 future 被解析之前完成它的 return,所以元素的集合是 returned 空的。
这是一个函数的示例:
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
,但我想尽我所能避免阻塞。
抱歉我的英语不好,如果我的问题不清楚我会编辑它来改进它。
感谢您的关注
首先,您应该将所有调用链接到您的 foreach 循环中:
val futures = sensorPositionParameters.deviceMacAddress.map (deviceMacAddress=>
for(
sensorHubs <- SensorHubRepository.sensorHubsFromDeviceMacAddress(deviceMacAddress);
processedSensorHubs <- processSensorHubs(sensorHubs)
) yield processedSensorHubs
)
这将为您提供期货清单。然后,您需要使用 Future.sequence(futures).
将此期货列表转换为列表的未来当然,这不是一个完整的解决方案。我希望你现在得到了如何避免使用 await 函数的提示