是否可以 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")。

希望这对你有用,在大多数情况下,这对我来说是最好的解决方案。