我有以下代码来调用API以获取我的数据,然后解析结果。我的理解是forEach循环上的“异步”没有阻塞,因此,如果我希望这些对象阻塞调用,我将使用输入布尔值进行设置。
我现在的问题是,我在某些调用中遇到了“套接字:打开的文件太多”错误,大概是因为我在API http响应上等待了太多事情而扑朔迷离(请告诉我如果您需要“ tx”功能的更多详细信息)
所以我的问题是这个。是否有一种快速的方法来限制下面的无阻塞“ forEach”循环,并可能要等待future.Delayed(Duration(milliseconds:250))在该循环中每第5次说一次?
当然,如果我只是在下面的代码中计数并等待异步调用,我认为forEach循环将继续进行其余的操作。
我是否必须对所有条目都做一个临时列表,并以非阻塞批处理的形式进行?
if (makeBlocking) {
for (var r in _commissionData[gwSerial].rooms.entries) {
Map<String, dynamic> res = await _getSetupRoomDevicesApi.tx(
_token, _clientId, gwSerialString, r.value.id);
Map<String, dynamic> res2 = await _listCommissionAssociations.tx(
_token, _clientId, gwSerialString, r.value.id);
processCommissionData(r.value, res, res2);
}
} else {
if (_commissionData != null) {
_commissionData[gwSerial]?.rooms?.forEach((roomId, r) async {
Map<String, dynamic> res = await _getSetupRoomDevicesApi.tx(
_token, _clientId, gwSerialString, r.id);
Map<String, dynamic> res2 = await _listCommissionAssociations.tx(
_token, _clientId, gwSerialString, r.id);
processCommissionData(r, res, res2);
});
}
}
好吧,这就是我最后要做的。我创建了一个小的函数,如果阻塞,可以等待,否则就可以等待。然后只需使用一个简单的for循环。
我遇到的问题是在地图上迭代,并且自然使用“ forEach”使它不会被阻塞。但是我想在该非阻塞循环中经常添加一个暂停(即油门)。但这意味着使用for循环,但是我无法使for循环主体“异步”。
也许我仍然不是“最好”的方式,所以欢迎反馈:
Future<void> syncGatewayRoomDeviceDetailData(
int gwSerial, bool makeBlocking) async {
if (_clientId == 0) {
setState(() {
_lastCommissionRoomUpdate = DateTime.now();
});
} else {
if (DateTime.now().difference(_lastCommissionRoomUpdate).inMilliseconds >
-1) {
print("Sync Gateway:$gwSerial blocking:$makeBlocking");
_lastCommissionRoomUpdate = DateTime.now();
String gwSerialString =
gwSerial.toRadixString(16).padLeft(8, '0').toUpperCase();
if (makeBlocking) {
for (var r in _commissionData[gwSerial].rooms.entries) {
await getAndProcessCommissionData(r, gwSerialString);
}
} else {
// Even if not blocking, still need to throttle
var throttleCount = 0;
for (var r in _commissionData[gwSerial].rooms.entries) {
if (++throttleCount % 9 == 0) {
await Future.delayed(Duration(milliseconds: 500));
}
getAndProcessCommissionData(r, gwSerialString);
}
}
} else {
print("sync delayed: $gwSerial ");
}
}
}
Future<void> getAndProcessCommissionData(var r, String gwSerialString) async {
Map<String, dynamic> res = await _getSetupRoomDevicesApi.tx(
_token, _clientId, gwSerialString, r.value.id);
Map<String, dynamic> res2 = await _listCommissionAssociations.tx(
_token, _clientId, gwSerialString, r.value.id);
processCommissionData(r.value, res, res2);
}