thunk関数によって自動的にgenerator関数を実行することを理解する.


今日はもう一度阮一峰先生の『Thunk関数の意味と使い方』を見ました.ここで自分の理解を整理します.
JavaScript言語では、Thunk関数は式ではなく、多パラメータ関数を単一パラメータのバージョンに置き換えて、引数としてのみコールバック関数を受け入れます.
//      readFile(     )
fs.readFile(fileName, callback);

// Thunk   readFile(     )
var readFileThunk = Thunk(fileName);
readFileThunk(callback);

var Thunk = function (fileName){
  return function (callback){
    return fs.readFile(fileName, callback); 
  };
};
ファイルの読み込みを例にします.次のGenerator関数は2つの非同期動作をカプセル化した.
var fs = require('fs');
var thunkify = require('thunkify');
var readFile = thunkify(fs.readFile);

var gen = function* (){
  var r1 = yield readFile('/etc/fstab'); // 2.      
  console.log(r1.toString());
  var r2 = yield readFile('/etc/shells');// 5.      
  console.log(r2.toString());
};
手動実行方式:
var g = gen();// 0.    

var r1 = g.next();// 1.      ,   r1  generator  :{value, done},    value      thunk  ,  thunk           
r1.value(function(err, data){// 3.             
  if (err) throw err;
  var r2 = g.next(data);// 4.      
  r2.value(function(err, data){ //             
    if (err) throw err;
    g.next(data);
  });
});
総じて言えば、thunk関数を利用して、必要な操作と対応するコールバック関数をfn(operation, callback)からfn(operation)(callback)の形に変えたということです.
なぜこのようにしますか?GEnerator関数は、yieldが戻った後、自動的に下に実行されないからです.
var gen = function* (){
  var r1 = yield readFile('/etc/fstab', gen.next()); //   gen      ,    generator  ,    next  , gen() !== gen(),       gen().next()
  console.log(r1.toString());
};
自動的には実行できないので、コールバック関数を第二ステップに分離して、コールバック関数の中で(この時はgeneratorが初期化されています.そうでないとコールバック関数に実行できません.)、generatorポインタのnext方法を実行して、次のステップに進みます.
総括:valueを実行する方法は本質的には1つのコールバック関数を登録するのに相当します.generator関数は非同期実行(実行権の引き渡し)を担当し、thunk関数は登録コールバック(実行権に戻り、次のステップを実行)を担当し、両者が結合して自動的にgenerator関数を実行します.
もし何か理解の不適切なところがあれば、ご指摘と交流を歓迎します.