为什么我的协程在我的普通函数之后被调用,尽管我的协程是先被调用的?

huangapple go评论53阅读模式
英文:

Why is my coroutine called after my normal function, even though my coroutine is called first?

问题

为什么我的协程在我的普通函数之后被调用,尽管我的协程是先调用的?

我尝试先调用CheckClass(),然后将返回值放入checkClassList,然后再调用JoinClass()函数,但无论我怎么做,JoinCLass()总是先被调用。

这是我的函数:

public void OnJoinClass()
{
    StartCoroutine(checkClass(studentId));
    print(classCheckList.Length);
    JoinClass(studentId, InputClassCode.text);
    print("成功");
}

这是我的CheckClass()协程:

IEnumerator checkClass(string id_Student)
{
    WWWForm form = new WWWForm();
    form.AddField("addStudentId", id_Student);

    WWW w = new WWW(URL5, form);

    yield return w;
    string classchecklist = w.text;

    classCheckList = classchecklist.Split(";");
    print(classCheckList.Length);
}

这是JoinCLass()函数:

public void JoinClass(string id_Student, string id_Class)
{
    for (int i = 0; i < classCheckList.Length; i++)
    {
        print(classCheckList[i] + "==" + id_Class + "\n");
        if (classCheckList[i] == id_Class)
        {
            print(classCheckList[i]);
            isJoined = true;
        }
    }

    if (!isJoined)
    {
        WWWForm form = new WWWForm();
        form.AddField("addStudentId", id_Student);
        form.AddField("addClassId", id_Class);

        WWW www = new WWW(URL4, form);
    }
    else
    {
        print("已加入班级");
    }
}
英文:

Why is my co-routine called after my normal function, even though my co-routine is called first

I tried to call CheckClass() first then put the return value to the checkClassList, then I call my JoinClass() function, but no matter how I put it, the JoinCLass() is always called first.

This is my function:

public void OnJoinClass()
{
    StartCoroutine(checkClass(studentId));
    print(classCheckList.Length);
    JoinClass(studentId, InputClassCode.text);
    print(&quot;succes&quot;);
}

This is my CheckClass() co-routine:

IEnumerator checkClass(string id_Student)
{
    WWWForm form = new WWWForm();
    form.AddField(&quot;addStudentId&quot;, id_Student);

    WWW w = new WWW(URL5, form);

    yield return w;
    string classchecklist = w.text;

    classCheckList = classchecklist.Split(&quot;;&quot;);
    print(classCheckList.Length);
}

And this is the JoinCLass() function:

public void JoinClass(string id_Student, string id_Class)
{
    for (int i = 0; i &lt; classCheckList.Length; i++)
    {
        print(classCheckList[i] + &quot;==&quot; + id_Class + &quot;\n&quot;);
        if (classCheckList[i] == id_Class)
        {
            print(classCheckList[i]);
            isJoined = true;
        }
    }

    if (!isJoined)
    {
        WWWForm form = new WWWForm();
        form.AddField(&quot;addStudentId&quot;, id_Student);
        form.AddField(&quot;addClassId&quot;, id_Class);

        WWW www = new WWW(URL4, form);
    }
    else
    {
        print(&quot;Sudah Masuk Kelas&quot;);
    }
}

答案1

得分: 2

第一个协程确实首先被调用,但由于您正在使用 yield return w 进行暂停,它会在请求完成后才继续执行。与此同时,您的代码会继续以同步方式运行,并启动另一个协程,该协程在 WWW 请求完成之前就已经完成。

如果您只使用一个协程,请在协程内部,在它产生结果之后调用 JoinClass

IEnumerator checkClass(string id_Student)
{
    WWWForm form = new WWWForm();
    form.AddField("addStudentId", id_Student);

    WWW w = new WWW(URL5, form);

    yield return w;
    string classchecklist = w.text;

    classCheckList = classchecklist.Split(";");
    print(classCheckList.Length);

    if (/* 满足条件 */) {
       JoinClass(studentId, InputClassCode.text);
    }
}

或者,您可以在第一个协程内部暂停第二个协程,并且在 Start 方法中移除对第二个协程的 StartCoroutine 调用。

查看我的答案,了解如何处理“主”和“从”协程的方法:
https://stackoverflow.com/a/76374713/7131671

英文:

The first coroutine does get called first, but since you're yielding: yield return w, it will yield after the request has finished. Meanwhile, your code continues running synchronously and it starts another coroutine, which finishes before the WWW request is fulfilled.

If you're using only one coroutine, simply call JoinClass inside the coroutine, after it yields the result.

IEnumerator checkClass(string id_Student)
{
    WWWForm form = new WWWForm();
    form.AddField(&quot;addStudentId&quot;, id_Student);


    WWW w = new WWW(URL5, form);

    yield return w;
    string classchecklist = w.text;

    classCheckList = classchecklist.Split(&quot;;&quot;);
    print(classCheckList.Length);

    if (/* condition is met */) {
       JoinClass(studentId, InputClassCode.text);
    }
}

Alternatively, it is possible to yield a second coroutine inside the first one and remove the StartCoroutine call for the second one in the Start method.

Check my answer here on how to handle "master" and "slave" coroutines:
https://stackoverflow.com/a/76374713/7131671

答案2

得分: 1

请注意,您在启动“checkClass”协程后立即调用“JoinClass”方法。但是,“checkClass”协程使用了“yield”,可能需要一些时间才能完成(肯定不会立即完成)。

因此,您应该在确保“checkClass”已完成后调用“JoinClass”。也许您可以像这样在“checkClass”方法内部调用JoinClass。

public void OnJoinClass()
{
    StartCoroutine(checkClass(studentId));
}

IEnumerator checkClass(string id_Student)
{
    WWWForm form = new WWWForm();
    form.AddField("addStudentId", id_Student);

    WWW w = new WWW(URL5, form);

    yield return w;
    string classchecklist = w.text;

    classCheckList = classchecklist.Split(";");
    print(classCheckList.Length);

    JoinClass(studentId, InputClassCode.text);
    print("成功");
}

public void JoinClass(string id_Student, string id_Class)
{
    for (int i = 0; i < classCheckList.Length; i++)
    {
        print(classCheckList[i] + "==" + id_Class + "\n");
        if (classCheckList[i] == id_Class)
        {
            print(classCheckList[i]);
            isJoined = true;
        }
    }

    if (!isJoined)
    {
        WWWForm form = new WWWForm();
        form.AddField("addStudentId", id_Student);
        form.AddField("addClassId", id_Class);

        WWW www = new WWW(URL4, form);
    }
    else
    {
        print("已加入班级");
    }
}

这是您提供的代码的翻译部分。

英文:

Be aware of that, you call "JoinClass" method right after starting "checkClass" coroutine. But "checkClass" coroutine uses "yield" and it may take a little time to complete (certainly will not complete immediately).

So you should call "JoinClass" after being sure that "checkClass" has completed. Maybe you can call JoinClass inside checkClass method like that.

public void OnJoinClass()
{
    StartCoroutine(checkClass(studentId));
}

IEnumerator checkClass(string id_Student)
{
    WWWForm form = new WWWForm();
    form.AddField(&quot;addStudentId&quot;, id_Student);


    WWW w = new WWW(URL5, form);

    yield return w;
    string classchecklist = w.text;

    classCheckList = classchecklist.Split(&quot;;&quot;);
    print(classCheckList.Length);

    JoinClass(studentId, InputClassCode.text);
    print(&quot;succes&quot;);
}



public void JoinClass(string id_Student, string id_Class)
{
    for (int i = 0; i &lt; classCheckList.Length; i++)
    {
        print(classCheckList[i] + &quot;==&quot; + id_Class + &quot;\n&quot;);
        if (classCheckList[i] == id_Class)
        {
            print(classCheckList[i]);
            isJoined = true;
        }
    }

    if (!isJoined)
    {
        WWWForm form = new WWWForm();
        form.AddField(&quot;addStudentId&quot;, id_Student);
        form.AddField(&quot;addClassId&quot;, id_Class);


        WWW www = new WWW(URL4, form);
    }
    else
    {
        print(&quot;Sudah Masuk Kelas&quot;);
    }
    
}

huangapple
  • 本文由 发表于 2023年6月1日 17:15:40
  • 转载请务必保留本文链接:https://go.coder-hub.com/76380373.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定