サーバーサイドJavaScript(Rhino)の継続でCoroutineを書いてみた

Scheme 入門 16. 継続の例。
2つのタスクを交互に呼ぶ。

  • 数字をプリントするタスク
  • 文字をプリントするタスク
var queue = [];

function coroutine(thunk) {
  queue.unshift(thunk);
}

function start() {
  (queue.pop())();
}

function pause() {
  var cc = new Continuation();
  coroutine(function() {cc(false);});
  start();
}

coroutine(function() {
            for (var i = 0; i < 5; i++) {
              print(i + 1);
              pause();
            };
          });

coroutine(function() {
            for (var i = 0; i < 5; i++) {
              print(String.fromCharCode(i + 97));
              pause();
            };
          });

start();

実行。(-opt -1は継続を使うためのオプション)

% rhino -opt -1 -f coroutine.js
1
a
2
b
3
c
4
d
5
e

この程度なら継続がなくても、JavaScript 1.7で入ったジェネレータで書ける。

<html>
  <body>
    <script type="application/javascript;version=1.7">
      function p0() {
        for (var i = 0; i < 5; i++) {
          yield (i + 1);
        }
      }
      function p1() {
        for (var i = 0; i < 5; i++) {
          yield String.fromCharCode(i + 97);
        }
      }
      var g0 = p0();
      var g1 = p1();
      for (var i = 0; i < 5; i++) {
        document.write(g0.next() + '<br>');
        document.write(g1.next() + '<br>');
      }
    </script>
  </body>
</html>
1
a
2
b
3
c
4
d
5
e