改写return

return其实可以被替换为单参数且永远不返回的函数,将return解糖进行CPS变换,改写为函数参数continuation,将迭代result作为回调参数返回,为引入异步迭代做准备。

  1. <?php
  2. final class AsyncTask
  3. {
  4. public $continuation;
  5. public function begin(callable $continuation)
  6. {
  7. $this->continuation = $continuation;
  8. $this->next();
  9. }
  10. public function next($result = null)
  11. {
  12. $value = $this->gen->send($result);
  13. if ($this->gen->valid()) {
  14. if ($value instanceof \Generator) {
  15. // 父任务next方法是子任务的延续,
  16. // 子任务迭代完成后继续完成父任务迭代
  17. $continuation = [$this, "next"];
  18. (new self($value))->begin($continuation);
  19. } else {
  20. $this->next($value);
  21. }
  22. } else {
  23. $cc = $this->continuation;
  24. $cc($result);
  25. }
  26. }
  27. }
  1. <?php
  2. function newGen()
  3. {
  4. $r1 = (yield newSubGen());
  5. $r2 = (yield 2);
  6. echo $r1, $r2;
  7. yield 3;
  8. }
  9. $task = new AsyncTask(newGen());
  10. $trace = function($r) { echo $r; };
  11. $task->begin($trace); // output: 123