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?
source to share
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? eg
www = 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; });
}
source to share