forEach() 循环的 Dart/Flutter 批处理?
Posted
技术标签:
【中文标题】forEach() 循环的 Dart/Flutter 批处理?【英文标题】:Dart/Flutter batching of a forEach() loop? 【发布时间】:2020-05-27 00:47:25 【问题描述】:我有以下代码调用 API 以获取我的数据,然后解析结果。我的理解是 forEach 循环上的“异步”不是阻塞的,因此我使用输入 bool 来设置是否希望这些阻塞调用。
我现在的问题是,我在某些调用中遇到了“套接字:打开的文件太多”错误,大概是因为我在等待 API http 响应时遇到了太多的问题(让我知道您是否需要“tx”函数的更多详细信息)
所以我的问题是这样的。有没有一种快速的方法来限制下面的非阻塞“forEach”循环,并且可能在循环中每 5 次对 future.Delayed(Duration(milliseconds:250)) 执行一次等待?
当然,如果我只是计算并等待下面代码中的异步调用,我认为 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 循环。问题是 Map好的,这就是我最终要做的。我创建了一个小函数,如果阻塞则可以等待,如果不阻塞则不等待。然后只需使用一个简单的 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);
【讨论】:
以上是关于forEach() 循环的 Dart/Flutter 批处理?的主要内容,如果未能解决你的问题,请参考以下文章