サーバーサイド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
- ファイバ、タスクシステムなどとも呼ばれる。
- 自分でタスク切り替えを呼んで、仲良く権利を譲り合うところから、協調的マルチタスキングとも。
- さらに発展して、プリエンプティブ・マルチタスクを継続を使って作る例