Flutter forEach()循环的省道/颤振批处理?
我有以下代码来调用API以获取数据,然后解析结果。我的理解是forEach循环上的“async”没有阻塞,因此我使用输入bool来设置是否希望这些调用阻塞 我现在的问题是,我在一些调用中遇到了一个“socket:too many open files”错误,可能是因为等待API http响应的东西太多(如果需要“tx”函数的更多细节,请告诉我) 所以我的问题是。是否有一种快速的方法来限制下面的非阻塞“forEach”循环,并可能对未来进行等待。延迟(持续时间(毫秒:250))是指每5次循环一次? 当然,如果我只是计数并等待下面代码中的异步调用,那么我认为forEach循环将继续正确地完成其余部分 我是否必须为所有条目制作一个临时列表,并以非阻塞批处理的方式进行Flutter forEach()循环的省道/颤振批处理?,flutter,dart,foreach,blocking,nonblocking,Flutter,Dart,Foreach,Blocking,Nonblocking,我有以下代码来调用API以获取数据,然后解析结果。我的理解是forEach循环上的“async”没有阻塞,因此我使用输入bool来设置是否希望这些调用阻塞 我现在的问题是,我在一些调用中遇到了一个“socket:too many open files”错误,可能是因为等待API http响应的东西太多(如果需要“tx”函数的更多细节,请告诉我) 所以我的问题是。是否有一种快速的方法来限制下面的非阻塞“forEach”循环,并可能对未来进行等待。延迟(持续时间(毫秒:250))是指每5次循环一次?
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);
});
}
}
if(makeBlocking){
对于(在_commissionData[gwSerial].rooms.entries中的变量r){
Map res=wait_getSetupRoomDevicesApi.tx(
_令牌,_clientId,gwSerialString,r.value.id);
Map res2=wait_listCommissionAssociations.tx(
_令牌,_clientId,gwSerialString,r.value.id);
processCommissionData(r.value、res、res2);
}
}否则{
如果(_commissionData!=null){
_commissionData[gwSerial]?.rooms?.forEach((roomId,r)异步{
Map res=wait_getSetupRoomDevicesApi.tx(
_令牌,_clientId,gwsserialstring,r.id);
Map res2=wait_listCommissionAssociations.tx(
_令牌,_clientId,gwsserialstring,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);
}
未来syncGatewayRoomDeviceDetailData(
int gwSerial,bool makeBlocking)异步{
如果(_clientId==0){
设置状态(){
_lastCommissionRoomUpdate=DateTime.now();
});
}否则{
if(DateTime.now().difference(_lastCommissionRoomUpdate).in毫秒>
-1) {
打印(“同步网关:$gwSerial blocking:$makeBlocking”);
_lastCommissionRoomUpdate=DateTime.now();
字符串gwSerialString=
gwSerial.toRadixString(16.padLeft(8,'0').toUpperCase();
if(makeBlocking){
对于(在_commissionData[gwSerial].rooms.entries中的变量r){
等待getAndProcessCommissionData(r,gwSerialString);
}
}否则{
//即使没有阻塞,仍然需要节流
var throttleCount=0;
对于(在_commissionData[gwSerial].rooms.entries中的变量r){
如果(++throttleCount%9==0){
等待未来。延迟(持续时间(毫秒:500));
}
getAndProcessCommissionData(r,gwSerialString);
}
}
}否则{
打印(“同步延迟:$gwSerial”);
}
}
}
Future getAndProcessCommissionData(var,字符串gwSerialString)异步{
Map res=wait_getSetupRoomDevicesApi.tx(
_令牌,_clientId,gwSerialString,r.value.id);
Map res2=wait_listCommissionAssociations.tx(
_令牌,_clientId,gwSerialString,r.value.id);
processCommissionData(r.value、res、res2);
}
是的,我想这是有道理的因为今天有这么多树,所以看不到森林。好吧,我明白为什么我不使用for循环。问题是,除非像我在上面的例子中那样抓取“.entities”,否则映射是不可编辑的。但是在这种情况下,我不能向for循环体添加“async”关键字。因此,我不能轻易地使for循环同时具有阻塞性和非阻塞性。for循环是阻塞的,foreach是非阻塞的。