Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Flutter forEach()循环的省道/颤振批处理?_Flutter_Dart_Foreach_Blocking_Nonblocking - Fatal编程技术网

Flutter 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次循环一次?

我有以下代码来调用API以获取数据,然后解析结果。我的理解是forEach循环上的“async”没有阻塞,因此我使用输入bool来设置是否希望这些调用阻塞

我现在的问题是,我在一些调用中遇到了一个“socket:too many open files”错误,可能是因为等待API http响应的东西太多(如果需要“tx”函数的更多细节,请告诉我)

所以我的问题是。是否有一种快速的方法来限制下面的非阻塞“forEach”循环,并可能对未来进行等待。延迟(持续时间(毫秒: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);
        });
      }
    }
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是非阻塞的。