2017-02-21 74 views
3

我有一個理解飛鏢和異步編程的未來功能的問題。我在網上找到的例子沒有回答我的問題,所以我會很感激社區的幫助。Dart未來的功能,請求回調

我有要求的玩家消息列表功能:

Future getMessagesInfo(response) async{ 
     dialogs = []; // I need this list to be filled to proceed 
     messagesList = response["data"]; 
     await getDialogsFunc(messagesList); 
     renderMessages(); 
    } 

這是前一個請求,這並不真正的問題在這裏的回調。 所以,這裏是getDialogsFunc,其目的是要貫穿一個清單,讓playerInfo每個ID在響應:

Future getDialogsFunc(messagesList) async{ 
     for(var i=0;i<messagesList.length;i++){ 
      if(messagesList[i]["player2"] != player.ID) await rm.getDialogInfo(messagesList[i]["player2"]); 
      if(messagesList[i]["player1"] != player.ID) await rm.getDialogInfo(messagesList[i]["player1"]); 
     } 
    } 

這裏是getDialogInfo,這實際上發出一個請求playerInfo並有一個回調函數,句柄收到的信息:

Future getDialogInfo(int id) async{ 
     messages = querySelector("account-messages-tab"); 
     var request = new Request(); 
     Object data = {"id": ServerAPI.PLAYER_INFO, "data":{"id": id}}; 
     await request.sendRequest(data,false, messages.onGotDialogInfo); 
    } 

請求是一個簡單的類,它處理的請求:

class Request{ 
    Future sendRequest(Object data, bool action,Function callback) async{ 
     HttpRequest request = new HttpRequest(); 
     String url = "http://example.com"; 
     await request 
      ..open('POST', url) 
      ..onLoadEnd.listen((e)=> callback(JSON.decode(request.responseText))) 
      ..send(JSON.encode(data)); 
    } 
} 

最後這裏是一個回調對於要求:

Future onGotDialogInfo(response) async{ 
     List dialog = new List(); 
     dialog.add(response["data"]["id"]); 
     dialog.add(response["data"]["login"]); 
     dialogs.add(dialog); 
} 

在第一個功能我想跑renderMessages()我收到有關的所有郵件信息後,讓dialogs列表應包含相關信息。在我用斷點測試的實現中,renderMessages()函數在回調之前運行。

我該怎麼做才能等待整個週期getDialogsFunc的功能,然後纔去renderMessages()

回答

2

whenComplete就像finally,無論請求是正常返回還是有錯誤,都會調用它。通常使用then

getDialogsFunc使用async但不使用await這是有點不尋常。這可能是你的意圖,但我不知道

Future getDialogsFunc(messagesList) async { 
    for(var i=0;i<messagesList.length;i++){ 
     if(messagesList[i]["player2"] != player.ID) 
      await rm.getDialogInfo(messagesList[i]["player2"]); 
     if(messagesList[i]["player1"] != player.ID) 
     await rm.getDialogInfo(messagesList[i]["player1"]); 
    } 
} 

getMessagesInfo然後可能看起來像:

void getMessagesInfo(response) await { 
    dialogs = []; // I need this list to be filled to proceed 
    messagesList = response["data"]; 
    await getDialogsFunc(messagesList) 
    renderMessages(messagesList); 
} 

我不知道在哪裏Request從何而來,因此很難說如何代碼應看起來像。它應該至少使用await爲其他await s按預期工作。

Future getDialogInfo(int id) async { 
    messages = querySelector("account-messages-tab"); 
    var request = new Request(); 
    Object data = {"id": ServerAPI.PLAYER_INFO, "data":{"id": id}}; 
    final response = await request.sendRequest(data,false); 
    messages.onGotDialogInfo(response) 
} 

更新

class Request{ 
    Future sendRequest(Object data, bool action) async{ 
     Completer completer = new Completer(); 
     HttpRequest request = new HttpRequest(); 
     String url = "http://example.com"; 
     await request 
      ..open('POST', url) 
      ..onLoadEnd.listen((_) { 
       if (request.readyState == HttpRequest.DONE) { 
       if (request.status == 200) { 
        // data saved OK. 
        completer.complete(JSON.decode(request.responseText)); // output the response from the server 
       } else { 
        completer.completeError(request.status); 
       } 
       } 
      }) 
      ..send(JSON.encode(data)); 

     return completer.future; 
    } 
} 
+0

您好!非常感謝您的回覆。我根據您的意見編輯了代碼,但仍未按預期工作。請求類是簡單的: '類請求{ \t未來sendRequest將(對象數據,BOOL動作,回調函數)異步{ \t \t的HttpRequest請求=新的HttpRequest(); \t \t String url =「http://example.com」; \t \t等待請求 \t \t \t ..open( 'POST',URL) \t \t \t ..onLoadEnd.listen((E)=>回調(JSON.decode(request.responseText))) \t \t \t ..send(JSON.encode(數據)); \t} }' –

+0

很難說。 「它不工作」不是太有用。請修改您的問題並在那裏發佈「請求」的代碼。評論中的代碼是不可讀的。 –

+0

我編輯了所有更正的代碼並添加了請求類代碼。 –