更有条理的方式来打电话给Coroutines?

在我的代码中,我需要在上一个完成后调用多个Web请求。 例如:

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

如果函数体是巨大的,它很容易混淆和混乱,在Javascript中,有Promise,所以我可以这样做:

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

任何人都有一个线索,我应该如何扩展Coroutines,以便我可以有类似的效果?

这非常简单。 只需使用yield return SecondRequest();yield return StartCoroutine( SecondRequest()); 。 在协程名称或StartCoroutine之前的yield应该使它等待该协程返回之后继续执行其下面的其他代码。

例如,您有四个应该按顺序调用的协同程序函数:

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

然后你可以这样做

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

编辑

如果我只获得成功状态,那么如果我只进入下一个协程怎么办? 比如www = new WWW(my_url); yield return www; if(!www.error) StartCoroutine(SecondRequest()); www = new WWW(my_url); yield return www; if(!www.error) StartCoroutine(SecondRequest());

在这种情况下,您应该使用Action作为协同程序函数中的参数:

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

用法

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