- WEB DB teppeis先生によると、generatorsはトランスパイルが難しいらしいので、generatorsが動く環境以外では使わないほうが良いとのこと。
- 2016/03/08時点では、compat-tableによると、Babelは次の3つのケースで☓がついている。
- can't use "this" with new
- %GeneratorPrototype%.constructor
- yield * on non-iterables is a runtime error
teppeis先生の金言
上二つはコンストラクタ関連なので、変なクラス作ってない限りは普通は無い。 下のは例外処理で、ありうる。 でもいまgeneratorをブラウザ向けで使ってるライブラリってbabel前提だから、そういうコードはたぶん含めないだろうな。
個人的には、いまバベルならgeneratorは採用しない。 バベらないなら使うけど、いまバベらないのってNode v4+対象のサーバー向けライブラリぐらいだからな
JavaScriptは基本的にSingle thread。なのでループ回数のめちゃ多いfor-loop等を呼び出しをしているfunctionが動作している間は、 timer処理中のconsole.log statementは割り込むことができない。
generatorsは、処理中に任意の回数pauseでき、あとからresumeすることができるこれまでのJavaScript関数とは異なる関数を提供する。 pauseしている間は別の関数が処理されることも許可する。
(JavaScriptにおいて)処理の割り込みができるということは、function間で協調(cooperate)できるということ。"cooperative"の反対の"preemptive" は、意図と反してprocess/functionが割り込みされることを表す。
ES2015 generators funcitonは並列動作におけるcooperativeである。yield
keywordを使ってgenerators内で処理をpauseすることができる。
yield
pauseが一度呼ばれるとgenerator自信ではresumeすることはできず、外部コントールからrestartする必要がある。
無限loop内でgenerators functionを指定すると永遠に終わらないプログラムになるが、用法用量守って使えばやりたいことが実現できる。
start/restartは単にgenerators functionをcontrolすることではなく、
処理をしながらgenerator内外で双方向メッセージのやり取りを可能にすることに意義がある。
generators functionを使って、互いのyield
にメッセージを送り、互いのrestartに対してメッセージを送信することができる。
function *foo() {
var x = 1 + (yield "foo");
console.log(x);
}
*
はgenerator function typeを示す。
yield
はstatementではなくexpression。
yield "foo"
expressionは、generator functionを止めた時に"foo"
という文字列を送信する。
そして、generatorがrestartするときに、送信される値が何であれそのexpressionの結果となる。
この例では、1
に結果がaddされてxにassignされる。
https://davidwalsh.name/es6-generators Syntax Please!から次回