2015-05-15 13 views
5

Tôi đang làm việc trên một trò chơi thống nhất và gặp phải một vấn đề mà tôi không thể giải quyết. Tôi đang kết nối với máy chủ web thông qua đối tượng WWW tiêu chuẩn và sử dụng một coroutine để thực thi yêu cầu POST.Unity - cần trả lại giá trị chỉ sau khi coroutine kết thúc

Mã hoạt động, nhưng tôi cần phải cập nhật giá trị biến và trả về biến đó khi kết thúc coroutine, mà tôi không thể làm.

public int POST(string username, string passw) 
{ 
    WWWForm form = new WWWForm(); 
    form.AddField("usr", username); 
    form.AddField("pass", passw); 

    WWW www = new WWW(url, form); 

    StartCoroutine(WaitForRequest(www)); 

    //problem is here ! 
    return success_fail; 
} 

private IEnumerator WaitForRequest(WWW www) 
{ 

    yield return www; 
    if (www.error == null) 
    { 

      if(www.text.Contains("user exists")) 
      { 

       success_fail = 2; 
      } 
      else 
      { 
       success_fail=1; 
      } 
    } else { 
     success_fail=0; 
    }  
} 

Coroutine cập nhật giá trị của 'success_fail' với giá trị có liên quan. Nhưng 'return success_fail;' dòng trong phương thức POST chạy trước khi coroutine kết thúc, làm cho nó trả về một giá trị sai.

Tôi đã cố gắng sử dụng một coroutine bổ sung nhưng không thành công, giả sử rằng tôi đã có một lỗi ở đó là tốt. Làm thế nào tôi có thể trả về giá trị 'success_fail' chỉ sau khi coroutine kết thúc?

Cảm ơn.

+0

Nếu bạn gọi một coroutine khác, nó sẽ đợi cho đến khi coroutine đó kết thúc. http://answers.unity3d.com/questions/276055/question-about-coroutines-and-waiting-for-a-functi.html – Shelby115

+0

Bạn đang trộn mã đồng bộ và không đồng bộ. Có lẽ một hàm gọi lại sẽ hữu ích? Bạn có thể sử dụng đại diện 'Action ', trong đó 'T' là bất kỳ kiểu nào bạn muốn" trả về ". – rutter

Trả lời

2

Chỉ một coroutine mới có thể chờ một coroutine khác. Vì bạn cần phải chờ cho coroutine bạn bắt đầu (WaitForRequest), nó có nghĩa là bạn phải chuyển đổi POST thành coroutine và nó sẽ không thể trả về int.

Có vẻ như success_fail là một biến thành viên, vì vậy nếu đó là tiếp xúc với bất cứ ai bắt đầu POST (như một coroutine), bạn sẽ không cần phải trả lại nó anyway.

public int success_fail 

IEnumerator POST(string username, string passw) 
{ 
    WWWForm form = new WWWForm(); 
    form.AddField("usr", username); 
    form.AddField("pass", passw); 

    WWW www = new WWW(url, form); 

    yield return StartCoroutine(WaitForRequest(www)); 
} 

private IEnumerator WaitForRequest(WWW www) 
{ 
    yield return www; 
    if (www.error == null) 
    { 
     if(www.text.Contains("user exists")) 
      { 
       success_fail = 2; 
      } 
      else 
      { 
       success_fail=1; 
      } 
    } else { 
     success_fail=0; 
    }  
} 

Về cơ bản, nếu bạn muốn mã của bạn "chờ", nó phải là một coroutine. Bạn không thể thực hiện cuộc gọi chờ đợi mà không chặn toàn bộ động cơ (không có loại hack vòng lặp nào).

chủ đề này đưa ra một cách mà bạn có thể trả lại int từ coroutine của bạn nếu bạn thực sự cần, nhưng POST vẫn không thể là một cuộc gọi chặn ...

http://answers.unity3d.com/questions/24640/how-do-i-return-a-value-from-a-coroutine.html

5

Chức năng làm không chờ đợi cho coroutines trước khi trở về, tuy nhiên bạn có thể sử dụng một hành động để cung cấp cho một số loại trở lại.

Đặt này trong chức năng Start của bạn

WWW www = new WWW("http://google.com"); 

StartCoroutine(WaitForRequest(www,(status)=>{ 
    print(status.ToString()); 
})); 

và thêm này.

private IEnumerator WaitForRequest(WWW www,Action<int> callback) { 
    int tempInt = 0; 
    yield return www; 
    if (string.IsNullOrEmpty(www.error)) { 
     if(!string.IsNullOrEmpty(www.text)) { 
      tempInt = 3; 
     } 
     else { 
      tempInt=2; 
     } 
    } else { 
     print(www.error); 
     tempInt=1; 
    } 
    callback(tempInt); 
} 

Hãy thử, mặc dù hàm có thể thay đổi giá trị không trả về giá trị và chỉ có một tham số. Vì vậy, trong bản chất này không phải là một giải pháp để trả lại coroutine của bạn tuy nhiên một khi nhận được int từ coroutine chúng tôi sau đó có thể biện minh cho những gì để làm với nó và thậm chí gọi các chức năng khác từ bên trong callback.

StartCoroutine(WaitForRequest(www,(status)=>{ 
    print(status.ToString()); 
    Awake(); // we can call other functions within the callback to use other codeblocks and logic. 
    if(status != 0) 
     print("yay!"); 
    } 
)); 

Điều này có thể được sử dụng cho bạn. http://answers.unity3d.com/questions/744888/returning-an-ienumerator-as-an-int.html

+2

Điều này thực sự phải là câu trả lời được chấp nhận. – Programmer

Các vấn đề liên quan