繁体   English   中英

DART异步/等待不等待

[英]DART async/await not waiting

因此,我一直在尝试DART(因此,我的核心语言是C ++和嵌入式C派生)。 因此,由于我更像是一个程序程序员,所以我的代码可能不太漂亮,但是我正在学习和学习...我一直在为与Future有关的问题而苦苦挣扎,基本上,我根本无法获得DART等待。 以下代码建立与小型嵌入式设备的套接字连接并提取信息。 一切正常,但请注意操作顺序应为main()从控制台获取一些信息,然后应调用方法cardStatus运行并通过套接字连接从嵌入式设备获取信息。 这就是等待发生的地方。 当返回Future时,它应该转到printstuff()方法。 我添加了应按顺序阅读的打印语句:

  • 这应该打印第一
  • 这应该打印第二
  • 这应该打印第三

相反,由于cardstatus调用没有等待(这很耗时),因此我得到:

  • 这应该打印第一
  • 这应该打印第三
  • 这应该打印第二

我在使用async时遵循了另一个线程,并且似乎至少遵循了使用该Other线程的一种可靠方法(我尝试使用.then和一个具有相同结果的完成器,所以我觉得有些核心我很想念)..但是我已经坚持了一个星期。

下面的代码以及控制台输出。

import 'dart:io';
import 'dart:async' show Future;

const String STATUS = "#111111;";

String defaultIP = "10.1.14.202";
int defaultConfigPort = 5111;
int defaultControlPort = 6722;

var card = new Map();

getInput(String defaults) {
  String takenin = stdin.readLineSync();
  if (takenin == '') takenin = defaults;
  return takenin;
}

Future main() async {
  stdout.write('What is the IP address of the card ($defaultIP): ');
  String ipaddress = getInput(defaultIP);
  defaultIP = ipaddress;
  print ("This should print 1st");
  stdout.writeln("Connecting to $defaultIP");
  await cardStatus(defaultIP, defaultConfigPort, STATUS, card);
  printstuff();
}

printstuff() {
  stdout.writeln(card['subnet']);
  print ("This should print 3rd");
}
Future cardStatus(String ip, int port, String message, Map card) {
  return new Future.delayed(Duration.ZERO, () {
    Socket.connect(ip, port).then((socket) {
      print('Connected to: '
          '${socket.remoteAddress.address}:${socket.remotePort}');

      socket.listen((data) {
        print(new String.fromCharCodes(data).trim());
        List str1 = (new String.fromCharCodes(data).trim().split(','));
        print(str1);
        print ("This should print 2nd");
        //var card = new Map();
        card['ip'] = str1[0];
        card['subnet'] = str1[1];
        card['gateway'] = str1[2];
        card['unknown'] = str1[3];
        card['persist'] = str1[4] == 'true';
        card['build'] = str1[5];
        card['serial'] = str1[6].substring(0, 14);
        card['cloudpassword'] = str1[6].substring(14, 20);
        card['DNS'] = str1[7];
        card['cloudhost'] = str1[8];
        card['cloudenabled'] = str1[9] == 'true';
        print(card['ip']);
      },
          onDone: () {
            print("Done");
            socket.destroy();
          });

//Send the request
      socket.write(message);
    });
  });
}

这是当前控制台输出。 注意,如果cardStatus将完成,则null不应为null,它将被打印为str1。

What is the IP address of the card (10.1.14.202): 
This should print 1st
Connecting to 10.1.14.202
null
This should print 3rd
Connected to: 10.1.14.202:5111
>10.1.14.202,255.255.255.0,10.1.14.1,,0,435,F44900A60040F8000000,192.168.1.1,connect.tutuuu.com,0;
[>10.1.14.202, 255.255.255.0, 10.1.14.1, , 0, 435, F44900A60040F8000000, 192.168.1.1, connect.tutuuu.com, 0;]
This should print 2nd
10.1.14.202
Done

Process finished with exit code 0

感谢您的所有帮助!

您在Socket.connect之前缺少return 就目前而言,您的代码只是开始连接,而永远不会等待它的将来。 我强烈建议尽可能多地使用新的await / async语法。

这是一个获取Google主页的正在运行的示例:

import 'dart:io';
import 'dart:async' show Future;

Future main() async {
  print("This should print 1st");
  await cardStatus('www.google.com', 80, 'GET /\nHTTP 1.1\n\n');
  printstuff();
}

printstuff() {
  print("This should print 3rd");
}

Future cardStatus(String ip, int port, String message) {
  return new Future.delayed(Duration.ZERO, () {
    return Socket.connect(ip, port).then((socket) {
      print('Connected to: '
          '${socket.remoteAddress.address}:${socket.remotePort}');

      socket.listen((data) {
        List str1 = (new String.fromCharCodes(data).trim().split(','));
        print(str1.first);
        print("This should print 2nd");
      }, onDone: () {
        print("Done");
        socket.destroy();
      }, onError: (e) {
        print("Error while listening: $e");
      });
      socket.write(message);
    });
  });
}

在稍稍编辑的版本下面使用等待,并尝试/捕获来处理错误:

import 'dart:io';
import 'dart:async' show Future;

Future main() async {
  print("This should print 1st");
  await cardStatus('www.google.com', 80, 'GET /\nHTTP 1.1\n\n');
  print("This should print 3rd");
}

Future<String> cardStatus(String ip, int port, String message) async {
  var socket = await Socket.connect(ip, port);
  print('Connected to: '
      '${socket.remoteAddress.address}:${socket.remotePort}');
  socket.write(message);
  print("Sent request");
  try {
    var response = await socket.fold(
        '',
        (String acc, List<int> data) =>
            acc + new String.fromCharCodes(data).trim());
    print("Received response: ${response.substring(0, 10)}");
    return response;
  } finally {
    socket.close();
  }
}

我知道它已经回答了,但是问题很严重,我对这个概念感到困惑,所以这是另一个让我理解的要素。 在dartpad( https://dartpad.dartlang.org/ )中尝试此操作(注释在代码中):

import 'dart:async';

//Just creating a duration to use later
Duration duration = new Duration(milliseconds: 500);

void main() {
  //This is what tricked me, printStuff is async so running in parallel processing by default
  //There is no need to call the function in a certain way (like a go xxx for a goroutine)
  //there is an await in the function so it will wait inside the function only 
  //i.e. printStuff('a') starts then printStuff('b') starts straight away...already in prallel processing
  //Run it and check the output 
  printStuff('a');
  printStuff('b');
  //Basically the await is in the function so printStuff is still returning a Future
  //i.e. printStuff('a') starts but doesn't wait to complete to start printStuff('b')   
}
Future<void> printStuff(String id) async {
  for(int i = 0; i <= 5; ++i) {
    //this await is waiting for the command to complete to move to the next iteration...
    //the i iterations are done one after the other
    await new Future.delayed(duration, () {
      print(id + i.toString()); 
    });   
  }    
}

然后试试这个:

import 'dart:async';

Duration duration = new Duration(milliseconds: 500);

//becuase I use await in main now, I must make it return a future and be async
Future main() async {
  //to make it happen one after the other, you need await at a call function level
  await printStuff('a');
  await printStuff('b');
  //Basically this says complete printStuff('a'), then start printStuff('b')...
  //and yes technically one doesn't need the second await becuase there is nothing after
}

Future<void> printStuff(String id) async {
  for(int i = 0; i <= 5; ++i) {
    await new Future.delayed(duration, () {
      print(id + i.toString());
    });
  }
}

因此,我个人的误解是异步函数立即被并行调用,而函数中的await则等待真正的但函数本身,而不会影响其他并行处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM