DART异步/等待不等待

mum*_*s01 2 asynchronous async-await dart

因此,我一直在尝试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);
    });
  });
}
Run Code Online (Sandbox Code Playgroud)

这是当前控制台输出。注意,如果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
Run Code Online (Sandbox Code Playgroud)

感谢您的所有帮助!

rkj*_*rkj 5

return以前不见了Socket.connect。就目前而言,您的代码只是开始连接,而永远不会等待它的将来。我强烈建议尽可能使用新的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);
    });
  });
}
Run Code Online (Sandbox Code Playgroud)

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

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();
  }
}
Run Code Online (Sandbox Code Playgroud)