Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
333 views
in Technique[技术] by (71.8m points)

c# - More organized way to call Coroutines?

In my code, I have multiple web requests needed to be called after the previous one is finished. For example:

void Init()
{
    StartCoroutine(FirstRequest());
}

IEnumerator FirstRequest()
{
    www = new WWW(my_url);
    yield return www;
    StartCoroutine(SecondRequest());
}

IEnumerator SecondRequest()
{
    www = new WWW(my_url);
    yield return www;
}

If the body of function is huge, it is relly easy to get confusing and messy,in Javascript, there is Promise, so I can do this:

function init() {  
  return validateParams()
    .then(firstRequest)
    .then(SecondRequest)
    .then((result) => {
      console.log(result)
      return result
    })
}

Any one has a clue how should I extend Coroutines so I can have similar effect?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is very straightforward. Just use yield return SecondRequest(); or yield return StartCoroutine( SecondRequest());. The yield before the the coroutine name or StartCoroutine should make it wait for that coroutine to return before it continue to execute other code below it.

For example, you have four coroutine functions that should be called sequentially:

IEnumerator FirstRequest()
{
    www = new WWW(my_url);
    yield return www;
}

IEnumerator SecondRequest()
{
    www = new WWW(my_url);
    yield return www;
}

IEnumerator ThirdRequest()
{
    www = new WWW(my_url);
    yield return www;
}

IEnumerator FourthRequest()
{
    www = new WWW(my_url);
    yield return www;
}

You can then do this:

void Init()
{
    StartCoroutine(doSequentialStuff());
}

IEnumerator doSequentialStuff()
{
    //Do first request then wait for it to return
    yield return FirstRequest();

    //Do second request then wait for it to return
    yield return SecondRequest();

    //Do third request then wait for it to return
    yield return ThirdRequest();

    //Do fourth request then wait for it to return
    yield return FourthRequest();
}

EDIT:

what if I only proceed to next coroutine if only I got success status? like www = new WWW(my_url); yield return www; if(!www.error) StartCoroutine(SecondRequest());

In this case, you should use Action as a parameter in the coroutine functions:

IEnumerator FirstRequest(Action<bool> reqStat)
{
    www = new WWW(my_url);
    yield return www;
    if (!string.IsNullOrEmpty(www.error))
        reqStat(false);
    else
        reqStat(true);
}

IEnumerator SecondRequest(Action<bool> reqStat)
{
    www = new WWW(my_url);
    yield return www;
    if (!string.IsNullOrEmpty(www.error))
        reqStat(false);
    else
        reqStat(true);
}

IEnumerator ThirdRequest(Action<bool> reqStat)
{
    www = new WWW(my_url);
    yield return www;
    if (!string.IsNullOrEmpty(www.error))
        reqStat(false);
    else
        reqStat(true);
}

IEnumerator FourthRequest(Action<bool> reqStat)
{
    www = new WWW(my_url);
    yield return www;
    if (!string.IsNullOrEmpty(www.error))
        reqStat(false);
    else
        reqStat(true);
}

Usage:

void Init()
{
    StartCoroutine(doSequentialStuff());
}

IEnumerator doSequentialStuff()
{
    bool reqStat = false;

    //Do first request then wait for it to return
    yield return FirstRequest((status) => { reqStat = status; });

    //Do second request then wait for it to return
    if (reqStat)
        yield return SecondRequest((status) => { reqStat = status; });

    //Do third request then wait for it to return
    if (reqStat)
        yield return ThirdRequest((status) => { reqStat = status; });

    //Do fourth request then wait for it to return
    if (reqStat)
        yield return FourthRequest((status) => { reqStat = status; });
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...