2017-07-07 391 views
1

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

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

而是因为等待是不发生在cardstatus呼叫(这很费时),我得到:

  • 这应该打印第1
  • 这应该打印3
  • 这应该打印第二

我跟着就利用异步的另一个线程,而且似乎用这个Other thread的一个坚实的方式至少以下(我尝试了。然后用一个类似的结果完成,所以有一些核心,我觉得我失踪)..但我一直坚持这一个星期。

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

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 

感谢您的帮助!

+1

请在发布一个简单的例子未来,大部分对你的问题并不感兴趣。 – rkj

+0

没问题。对于那个很抱歉。 – mumcs01

回答

4

您在Socket.connect之前缺少return。就目前而言,您的代码只是开始连接,但从未等到未来。我强烈建议尽可能使用新的await/async语法。

这里是一个正在运行的例子,的确让谷歌主页:

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); 
    }); 
    }); 
} 

下面使用等待着轻微删节版,和try/catch来处理错误:

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(); 
    } 
} 
+0

非常感谢。这确实有用。花了我一点时间去了解这一点,并等待语法。我想我正在被另一个线程绊倒,说异步只在'调用者'方法中需要。我知道有很多关于什么时候你应该使用等待,什么时候不使用的线程。这个用法的原理非常简单,但不知怎的,我却不知道何时使用它的实用性,什么时候我不需要......我要回去重读它......说到这一点,当我阅读你的try/catch版本时,它完全有道理。再次感谢。 – mumcs01

+1

只是一个为什么我被绊倒的例子 - 我原来的例子中的getInput()使用stdin.readLineSync(),它本身意味着等待并暂停操作....很难解释,但我看到线程中的其他人一直在努力争取相同的概念,我相信这与我在程序化单线程编程中的基础教育有关。 – mumcs01

+0

这是超级棘手,我不知道一个人不会偶然发现类似的问题:) – rkj