co函数和thunk函数作用都是让Generator函数自动执行,无需用户手动调用next方法

  1. var gen = function* (){
  2. var f1 = yield readFile('/etc/fstab');
  3. var f2 = yield readFile('/etc/shells');
  4. console.log(f1.toString());
  5. console.log(f2.toString());
  6. };

co函数可以让你不用编写Generator函数的执行器

  1. var co = require('co')
  2. co(gen).then(() => {
  3. console.log("Generator函数执行")
  4. })

co函数前提条件:Generator函数的yield命令后面,只能是Thunk函数或者Promise对象。
thunk函数用的比较少,这里省略。主要看基于Promise对象的自动执行器。

基于Promise对象的自动执行

下面对fs.readFile进行Promise封装

  1. var fs = require('fs')
  2. var readFile = function (fileName) {
  3. return new Promise((resolve, reject) => {
  4. fs.readFile(fileName, (error, data) => {
  5. if (error) reject(error);
  6. reject(data)
  7. })
  8. })
  9. }
  10. var gen = function* () {
  11. var f1 = yield readFile('/etc/fstab');
  12. var f2 = yield readFile('/etc/shells');
  13. console.log(f1.toString());
  14. console.log(f2.toString());
  15. }

手动执行

对于f1、f2 两行的手动操作,readFile是一个promise对象,所以可以通过then方法,直接拿到读取文件成功的回调,这时将成功的value赋值给f1,作为下一个next方法的参数

  1. var g = gen()
  2. g.next().value.then(data => {
  3. g.next(data).value.then(data => {
  4. g.next(data).value.then...
  5. })
  6. })

自动执行

对于操作较少的generator函数,手动执行看起来很方便,但面对函数多的情况,还一个个手动执行就很费力;下面是自动执行的方法

  1. function autoRun(gen) {
  2. var g = gen();
  3. function next(data) {
  4. var result = g.next(data);
  5. if (result.done) return result.value;
  6. result.value.then(data => {
  7. next(data);
  8. });
  9. }
  10. next();
  11. }
  12. autoRun(gen);