Suspending calls
The ability to suspend and later resume execution is the most important aspect of a coroutine. There are multiple ways to suspend a coroutine:
suspend()
,terminate()
,accept()
oryield(...)
, or- a call to a
@:pecan.action
or@:pecan.accept
function
suspend()
The suspend()
call is always available within a coroutine body. It simply suspends the coroutine until it is woken up again externally with a wakeup()
call.
Example: suspend()
call
var co = pecan.Co.co({
trace(1);
suspend();
trace(3);
}).run();
trace(2);
co.wakeup();
// output: 1, 2, 3
terminate()
The terminate()
call stops execution of the coroutine immediately, and prevents it from being woken up again. No error is thrown and the returned
field is not updated.
Example: terminate()
call
var co = pecan.Co.co({
trace(1);
suspend();
terminate();
trace(3);
}).run();
trace(2);
co.wakeup();
// output: 1, 2
Custom suspending functions
It is possible to declare methods as suspending. These methods must:
- have the
:pecan.action
metadata and - take the coroutine
pecan.ICo<...>
as their last argument, ideally optional.
Functions declared this way can then be called from within coroutines, with the last argument being replaced by the coroutine instance automatically.
Example: haxe.Timer.delay
as a suspending function
class Foobar {
@:pecan.action public static function delay(
ms:Int,
?co:pecan.ICo<Any, Any, Any>
):Void {
haxe.Timer.delay(co.wakeup, ms);
co.suspend();
}
}
Usage:
pecan.Co.co({
trace("Hello,");
Foobar.delay(1000); // one second delay
trace("Haxe!");
}).run();
Note that a @:pecan.action
function is not automatically suspending. If there is no co.suspend()
call, the coroutine will continue after the call as usual.