Yeoman创建自己的generator(2)

来源:互联网 发布:销售管理系统java编程 编辑:程序博客网 时间:2024/06/05 13:28

Generator 运行时上下文

一个最重要的概念,是去弄清楚,当你编写一个generator的时候,其中的方法是如何运行的和在哪个上下文中

被当作action的prototype方法

每个被添加到generator原型链上的方法都会被当成一个任务.每个任务都跑在一个队列中,这个队列由yeoman的运行环境来决定

换句话说,通过Object.getPrototypeOf(Generator) 返回的每个函数都会被自动运行

帮助函数和私有函数

你现在知道prototype上的方法都会被当作是一个任务,你可能想知道怎么去定义一些帮助函数私有函数(不会被当作任务自动运行的函数).这里有三种方式来完成这点.

  • 通过“_”来作为方法前缀,比如”_private_say”
  • 使用实例方法
    generators.Base.extend({        constructor: function () {          this.helperMethod = function () {            console.log('won\'t be called automatically');          };        }      });

扑满大师:了解js的人应该知道,直接上述的方式写,其实是不绑定在prototype上的

  • 扩展父类generator
      var MyBase = generators.Base.extend({        helper: function () {          console.log('methods on the parent generator won\'t be called automatically');        }      });      module.exports = MyBase.extend({        exec: function () {          this.helper();        }      });

扑满大师:很取巧的方式,因为Object.getPrototypeOf(Generator) 是不会找prototype的prototype的

运行循环圈

运行单个的generator,那么运行队列是很清楚的.但是一旦你要把多个generator组合在一起使用,那么这个还不够

这个是为什么yeoman使用运行循环圈 的原因

运行循环圈是一个优先队列系统.我们使用分组队列模块来处理它

优先权在你的代码中被定义,它们要被命名为特殊的prototype名字.当方法名被定义成”priorityName”这样的格式的时候,运行循环圈会把这个方法压入特殊的队列.如果不是,那么会被压入默认的组中

在代码中,它应该是这样:

generators.Base.extend({  priorityName: function () {}});

你也可以把多个方法放在一个对象中赋值给priorityName,请注意他们的运行顺序

generators.Base.extend({  priorityName: {    method: function () {},    method2: function () {}  }});

一些可能的优先权的值(以运行顺序排列):

  • initializing - 你的初始方法 (检查当前工程状态,读取配置文件等等)
  • prompting - 当你提醒用户来确定一些选项的时候(你需要使用this.prompt())
  • configuring - 保存配置和配置工程(创建.editorconfig文件和其他的一些元数据文件)
  • default - 如果方法名不配对priority,那么会被压入这个group
  • writing - 创建generator的特定文件(比如routes, controllers等等)
  • conflicts - 冲突的时候
  • install - 使用npm bower等工具进行安装的时候
  • end - 最后调用,清理

跟随这些priority的知道,你的generator会跟其他的generator很好的共同工作

异步任务

有很多方法可以来暂停”运行循环圈”,直到异步任务已经被完成

最简单的方式就是返回一个promise.一旦promise完成了,那么循环圈会继续;如果promise失败了,那就会抛出一个错误,并且停止.

如果你依赖的异步api不是promise方式的,那么你可以用this.async()方式,调用它会返回一个function,在任务中调用这个function,yeoman就知道你的任务完成了

asyncTask: function () {  var done = this.async();  getUserEmail(function (err, name) {    done(err);  });}

如果done函数被调用的时候带上了error参数,那么”运行循环圈”会被停止,并且抛出一个错误

0 0
原创粉丝点击