如何使协程按顺序运行?

3

这是使用Unity3D。我有三个协程: GetJSONFromSelectedSubreddit(), LoadMoreMemes(), 以及在一个单独的脚本中需要能够通过GetNewMemes()函数(必须返回类型为Meme[])访问memes数组的函数。LoadNewMemes() 生成了这个数组。问题是,LoadMoreMemes() 需要json才能运行,所以它们必须按照提到的顺序运行。如果你需要这些函数,这里它们:

public void GetNewMemes(string subReddit, int count)
{
    SetSelectedSubreddit(subReddit);
    memesAtATime = count;
    subJSON = null;
    StartCoroutine(GetJSONFromSelectedSubreddit());
    StartCoroutine(LoadMoreMemes());
}

IEnumerator GetJSONFromSelectedSubreddit()
{
    gettingJSON = true;
    WWW requester = new WWW("https://www.reddit.com/r/" + selectedSub + "/new.json?sort=new&count=25&after=" + postIndex);
    yield return requester;
    subJSON = requester.text;
    json = new JSONObject(subJSON);
    gettingJSON = false;
}

IEnumerator LoadMoreMemes()
{
    while (gettingJSON)
        yield return new WaitForSeconds(0.1f);
    for (int i = 0; i < memesAtATime; i++)
    {
        yield return StartCoroutine(GetUserPostKarma(json["data"]["children"][i]["data"]["author"].str));

        string sourceURL = json["data"]["children"][i]["data"]["preview"]["images"][0]["source"]["url"].str;
        sourceURL = sourceURL.Replace("&amp;", "&");

        yield return StartCoroutine(GrabImage(sourceURL));

        Meme currentMeme = new Meme(
                json["data"]["children"][i]["data"]["preview"]["images"][0]["source"]["url"].str,
                authorPostKarma,
                (int) json["data"]["children"][i]["data"]["score"].i,
                json["data"]["children"][i]["data"]["permalink"].str,
                json["data"]["children"][i]["data"]["title"].str,
                currentBitmap
        );
        Debug.Log(currentMeme.cost);
        memes[i] = currentMeme;
    }
}

这是另一个脚本:

以下是另一段代码:

void Start ()
{
    RedditCommunicator redditCommunicator = GetComponent<RedditCommunicator>();
    redditCommunicator.GetNewMemes("me_irl", 1);
    Meme[] memes = redditCommunicator.GetCurrentMemes();
    Debug.Log(memes[0].currentScore);
    redditCommunicator.SpawnOneMeme(memes[0]);
}

每个函数单独运行都没有问题,但是它们需要等待彼此完成,并按正确顺序运行才能正常工作。我希望这些函数保持分离,以便将来可以单独调用它们。memes是一个私有变量,我想将其传递给调用这些函数的其他脚本。如果您认为我已经通过谷歌和自学尽了最大努力,那么请相信我。非常感谢您的帮助。如果需要更多信息,请随时向我提问。目前代码的状态是在协程完成之前就返回了memes,导致memes为空。
2个回答

2
您可以在IEnumerator中产生一个Coroutine,这将暂停该Coroutine的进程,直到该Coroutine完成。代码示例如下:
void Start()
{
    StartCoroutine(DoThings((text) => {
        Debug.Log("Dothings told me: " + text);
    }));
}

IEnumerator DoThings(Action<string>() callback)
{
    yield return StartCoroutine(DoThisFirst());
    callback("Returning a value mid-method!");
    yield return StartCoroutine(ThenThis());
    Debug.Log(3);
}

IEnumerator DoThisFirst()
{
    yield return new WaitForSeconds(1);
    Debug.Log(1);
}

IEnumerator ThenThis()
{
    yield return new WaitForSeconds(1);
    Debug.Log(2);
}

我调用的函数会在DoThings完成之前返回一个值。我不得不使它返回void,并且让枚举器设置一个公共变量,然后从其他脚本中获取它。我宁愿不这样做,但如果这是我必须要做的... - Techn0mancer
我不是很确定我理解了,但我会更新帖子,向您展示如何实现回调。 - Fredrik Schön

-1
问题在于,在GetNewMemes方法中,GetJSONFromSelectedSubredditLoadNewMemes方法被调用为两个“并行”的协程。
如果您不需要“异步”运行协程,您可以直接枚举它:
public void GetNewMemes(string subReddit, int count)
{
    SetSelectedSubreddit(subReddit);
    memesAtATime = count;
    subJSON = null;

    var enumerator = GetJSONFromSelectedSubreddit();
    while (enumerator.MoveNext());

    enumerator = LoadNewMemes();
    while (enumerator.MoveNext());
}

协程不是异步的。 - Galandil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接