2017-07-07 390 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