2016-06-28 74 views
0

我试图从GET请求中保存一些数据。我使用StartCoroutine来请求并使用Lambda表达式来保存数据。GET请求不保存数据

我的代码是这样的:

Using UnityEngine; 
    using System.Collections; 

    public class Test : MonoBehaviour { 

// Use this for initialization 
public void Start() { 
    string url1 = "http://localhost/virtualTV/query/?risorsa="; 

    string ciao = "http://desktop-pqb3a65:8080/marmotta/resource/ef299b79-35f2-4942-a33b-7e4d7b7cbfb5"; 
    url1 = url1 + ciao; 

    WWW www1 = new WWW(url1); 

    var main=new JSONObject(JSONObject.Type.OBJECT); 
    var final= new JSONObject(JSONObject.Type.OBJECT);; 
    StartCoroutine(firstParsing((value)=>{main = value; 
     final= main.Copy(); 
     Debug.Log(main); 
    })); 
    Debug.Log(final); 
} 

public IEnumerator firstParsing(System.Action<JSONObject> callback) 
{ 
    string url2 = "http://localhost/virtualTV/FirstQuery/?risorsa="; 
    string ciao = "http://desktop-pqb3a65:8080/marmotta/resource/ef299b79-35f2-4942-a33b-7e4d7b7cbfb5"; 
    url2 = url2 + ciao; 
    WWW www2 = new WWW(url2); 
    yield return www2; 
    string json = www2.text; 

    //Parsing del json con creazione di un array 
    var firstjson = new JSONObject(json); 
    var tempVideo = new JSONObject(JSONObject.Type.OBJECT); 
    var array2 = new JSONObject(JSONObject.Type.OBJECT); 

      tempVideo.AddField ("id", firstjson.GetField ("id")); 
      tempVideo.AddField ("type", firstjson.GetField ("type")); 
      tempVideo.AddField ("url", firstjson.GetField ("url")); 
      array2.Add (tempVideo); 

    yield return array2;  
    callback (array2); 
    Debug.Log ("First Run" + array2); 

} 

当我尝试的命令后使用FINAL,

final=main.copy() 

它是空的。你能帮我把价值保存在变量final吗?谢谢大家。

+0

'Debug.Log(main);'?的输出是什么? –

+0

它包含我想要在最终存储的JSON,它不能在变量final中复制变量main,如果我最终打印到包含JSON的StartCoroutine中,那么它是空的 – user3836982

+0

您是否收到任何错误? –

回答

3

协程的执行分布在多个帧中。当协程遇到yield return语句时,它返回到调用方法,该方法结束执行,直到任务结束。


在你的情况,在StartDebug.Log(final)声明只要yield return www2;firstParsing执行执行。回调尚未被调用,这就是为什么final为空。

为了能够final访问该值已分配后外的回调函数,你必须设置该final在回调后分配设置true一个bool。事情是这样的:

StartCoroutine(firstParsing((value)=>{main = value; 
    final= main.Copy(); 
    Debug.Log(main); 
    isFinalAssigned = true; 
})); 

// In another method 
if(isFinalAssigned) 
{ 
    // Access final 
} 

你必须要注意的是,上述if语句只在一个被称为定期像Update方法是有用的。如果您正在使用仅调用一次的方法访问final(例如OnEnable),则必须等待分配final。您可以使用另一种协同程序完成这个任务好像

IEnumerator DoSomethingWithFinal() 
{ 
    while(!isFinalAssigned) 
     yield return null; // Wait for next frame 
    // Do something with final 
} 

了最简单的方法是在消耗你的callback(访问)final

编辑2:从您的意见,你可以做下面的事情。你会使用协程,因为阻塞主游戏线程不是一个好主意。

private JSONObject final = null; // Make final a field 

无论你在哪里使用final,你有两个选择。

  1. 使用空检查if(final == null) return;这可能是不切实际的。
  2. 等待final在协程中分配并做一些回调。这是你可以干净地做你想做的事情的唯一方法。

请看下面的实施。

// Calls callback after final has been assigned 
IEnumerator WaitForFinal(System.Action callback) 
{ 
    while(final == null) 
     yield return null; // Wait for next frame 
    callback(); 
} 

// This whole method depends on final. 
// This should be similar to your method set up if you have 
// good coding standards (not very long methods, each method does only 1 thing) 
void MethodThatUsesFinal() 
{ 
    if (final == null) 
    { 
     // Waits till final is assigned and calls this method again 
     StartCoroutine(WaitForFinal(MethodThatUsesFinal)); 
     return; 
    } 

    // use final 
} 
+0

你可以给我一个例子,以获得最广泛的方法访问广告变量最后? Becausa我尝试使用第一种方法,但它从未分配变量final。非常感谢 – user3836982

+0

我在调用StartCoroutine的同一个方法中使用变量final。 – user3836982

+0

您可以将代码移动到另一个方法吗?如果您需要访问本地变量,您可以将您的访问代码移动到您拥有的回调中。你能准确地告诉我们你想用'final'做什么吗?我说的第一种方法在“开始”方法中不起作用,而第二种方法将起作用。 – EvilTak