forEach()循环的Dart / Flutter批处理?

问题描述 投票:0回答:1

我有以下代码来调用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);
        });
      }
    }
flutter dart foreach blocking nonblocking
1个回答
0
投票

好吧,这就是我最后要做的。我创建了一个小的函数,如果阻塞,可以等待,否则就可以等待。然后只需使用一个简单的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);
  }
© www.soinside.com 2019 - 2024. All rights reserved.