A more organized way to call Coroutines?

In my code, I have several web requests that need to be called after the previous one completes. 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 function body is huge it easily gets confusing and messy, there is a Promise in Javascript, so I can do this:

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

      

Does anyone know how I can extend Coroutines so that I can have a similar effect?

+3


source to share


1 answer


It's very simple. Just use yield return SecondRequest();

or yield return StartCoroutine( SecondRequest());

. yield

before the coroutine name, or StartCoroutine

should make it wait for that coprocessor to return before it continues executing other code below it.

For example, you have four coroutine functions that must 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;
}

      

Then you can do the following:

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 go to the next coroutine if only i got a success status? egwww = new WWW(my_url); yield return www; if(!www.error) StartCoroutine(SecondRequest());

In this case, you should use Action

as a parameter in accompanying 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);
}

      

Using:

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; });
}

      

+5


source







All Articles