是否可以 return 来自 Coroutine 方法的 UnityWebRequest 的结果?
Is it possible to return the result of an UnityWebRequest from Coroutine method?
我正在尝试 return 来自协程方法的 UnityWebRequest 请求的结果,我想到了类似以下代码的内容:
private IEnumerator<string> SendPostWebRequest(string url)
{
WWWForm form = new WWWForm();
form.AddField("Key", "Value");
using (UnityWebRequest request = UnityWebRequest.Post(url, form))
{
yield return request.SendWebRequest();
if (!request.isNetworkError && !request.isHttpError && request.isDone)
yield return request.downloadHandler.text;
yield return string.Empty;
}
}
但是这一行有一个错误(yield return request.SendWebRequest()),我不知道如何修复它! (这里需要一个yield,等待请求完成)
我可以看到这个函数 return 类型是 IEnumerator,并且注意到 'request.SendWebRequest();' return 一个 Task。所以解决这个问题的第一件事就是删除通用类型,就像这样:
private IEnumerator<string> SendPostWebRequest(){....}
另一方面,你需要return一个字符串。根据 Unity 的文档,以下代码应该适用于函数不是协程的情况:
string str = (string) SendPostWebRequest(...);
这将转换 IEnumerator 中产生的所有元素,并将 return 第一个字符串元素放在它上面。
但是,这是一个协程,根据我的经验,这是行不通的。我想出并经常使用的解决方案是使用 lambda 函数。
要解决这个问题,您需要向您的函数添加一个额外的参数,一个 Action(基本上是函数引用),以便您可以从 SendPostWebRequest() 函数中执行它。我听起来很困惑,但请看一下这段代码。这就是我通常实现这种事情的方式。
public void ExampleFunction(){
// Using lambda function
StartCoroutine(SendPostWebRequest("www.google.es", (string ReturnResult)=>
Debug.Log(ReturnResult)
));
// Using functions references
StartCoroutine(SendPostWebRequest("www.google.es", OtherResultManagementFunction));
}
private void OtherResultManagementFunction(string ReturnResult){
Debug.Log(ReturnResult);
}
private IEnumerator SendPostWebRequest(string url, Action<string> FinishDelegate)
{
WWWForm form = new WWWForm();
form.AddField("Key", "Value");
using (UnityWebRequest request = UnityWebRequest.Post(url, form))
{
yield return request.SendWebRequest();
if (!request.isNetworkError && !request.isHttpError && request.isDone)
yield return request.downloadHandler.text;
FinishDelegate("WHATEVER STRING");
}
}
泛型Action指定return封装在Action对象中的函数的时间。
两个协程的工作方式完全相同,但第一个使用 lambda 函数,另一个使用函数引用。如果执行,两者都会打印来自网络请求的字符串 returned(在本例中为 "WHATEVER STRING")。
希望这对你有用,在大多数情况下,这对我来说是最好的解决方案。
我正在尝试 return 来自协程方法的 UnityWebRequest 请求的结果,我想到了类似以下代码的内容:
private IEnumerator<string> SendPostWebRequest(string url)
{
WWWForm form = new WWWForm();
form.AddField("Key", "Value");
using (UnityWebRequest request = UnityWebRequest.Post(url, form))
{
yield return request.SendWebRequest();
if (!request.isNetworkError && !request.isHttpError && request.isDone)
yield return request.downloadHandler.text;
yield return string.Empty;
}
}
但是这一行有一个错误(yield return request.SendWebRequest()),我不知道如何修复它! (这里需要一个yield,等待请求完成)
我可以看到这个函数 return 类型是 IEnumerator,并且注意到 'request.SendWebRequest();' return 一个 Task。所以解决这个问题的第一件事就是删除通用类型,就像这样:
private IEnumerator<string> SendPostWebRequest(){....}
另一方面,你需要return一个字符串。根据 Unity 的文档,以下代码应该适用于函数不是协程的情况:
string str = (string) SendPostWebRequest(...);
这将转换 IEnumerator 中产生的所有元素,并将 return 第一个字符串元素放在它上面。
但是,这是一个协程,根据我的经验,这是行不通的。我想出并经常使用的解决方案是使用 lambda 函数。
要解决这个问题,您需要向您的函数添加一个额外的参数,一个 Action(基本上是函数引用),以便您可以从 SendPostWebRequest() 函数中执行它。我听起来很困惑,但请看一下这段代码。这就是我通常实现这种事情的方式。
public void ExampleFunction(){
// Using lambda function
StartCoroutine(SendPostWebRequest("www.google.es", (string ReturnResult)=>
Debug.Log(ReturnResult)
));
// Using functions references
StartCoroutine(SendPostWebRequest("www.google.es", OtherResultManagementFunction));
}
private void OtherResultManagementFunction(string ReturnResult){
Debug.Log(ReturnResult);
}
private IEnumerator SendPostWebRequest(string url, Action<string> FinishDelegate)
{
WWWForm form = new WWWForm();
form.AddField("Key", "Value");
using (UnityWebRequest request = UnityWebRequest.Post(url, form))
{
yield return request.SendWebRequest();
if (!request.isNetworkError && !request.isHttpError && request.isDone)
yield return request.downloadHandler.text;
FinishDelegate("WHATEVER STRING");
}
}
泛型Action指定return封装在Action对象中的函数的时间。
两个协程的工作方式完全相同,但第一个使用 lambda 函数,另一个使用函数引用。如果执行,两者都会打印来自网络请求的字符串 returned(在本例中为 "WHATEVER STRING")。
希望这对你有用,在大多数情况下,这对我来说是最好的解决方案。