java - 为什么 `break label` 不能在 lambda 表达式中使用?任何解决方法?
问题描述
我正在尝试使用 HTTPClient 库为 HTTP 请求实现重试机制。对于重试机制,我有一个要尝试的网站列表,我会尝试每个网站retries
多次。当我收到status 200
来自任何请求的 a 时,该过程结束。
我的想法是使用 booleanrequestSuccess
和 label requestLabel
。当我requestSuccess = true
收到requestLabel
一个status 200
. 但是,变量必须是(effectively) final
并且break
标签在 lambda 表达式中不可用。
是否有任何解决方法来实现这种重试机制?
boolean requestSuccess = false;
requestLabel:
for(String site: sites) {
for(int i = 0; i < retries; i++) {
client.request(site, data, requestOptions, (err, res, content) -> {
if(err == null) {
requestSuccess = true;
break requestLabel;
} else {
log(...);
}
})
}
}
if(!requestSuccess) {
log("request failed");
}
一种可能的答案
受提交然后删除的答案的启发,我可以使用类似包装类的解决方案。我认为它会工作,但它似乎很脏?
boolean[] requestSuccess = new boolean[1];
requestLabel:
for(String site: sites) {
for(int i = 0; i < retries; i++) {
if(requestSuccess[0] == true) {
break requestLabel;
}
client.request(site, data, requestOptions, (err, res, content) -> {
if(err == null) {
requestSuccess[0] = true;
} else {
log(...);
}
})
}
}
if(!requestSuccess) {
log("request failed");
}
解决方案
一个 lambda 在引擎盖下变成了它自己的类。就 java 解释器而言,就好像你有两个类。
class Main {
public void runstuff() {
labelX:
for(...) {
client.request(new Main$Foo().xyz(.....));
}
}
class Foo {
public xyz(....) {
break labelX; // There is no labelX to break to here in Foo.xyz
}
}
}
推荐阅读
- python - 散景时间序列图表轴日期滑块
- docker - Redis 作为容器/POD 的 Sidecar?
- git - git 命令警告说重定向到
.git - node.js - 如何使用 nodeJS 和 express 为 OpenShift 应用程序配置路由
- php - 如何仅为未登录的用户隐藏 Woocommerce 产品描述选项卡?
- docker - 如何修复 ln -s 在 Docker 中不起作用?
- python - 需要帮助错误消息“int”对象没有属性“追加”
- lisp - 使用返回两个数字中较小者的另一个函数定义“最小”函数以返回列表的最小值
- matlab - 在不使用 for 循环的情况下对矩阵的子矩阵求和
- php - 如何根据用户在 Laravel 6 中注册的服务动态地将用户带到某些路线