@bornkiller
2014-11-28T07:37:33.000000Z
字数 2096
阅读 2722
nodejs
Nodejs在0.11.x后开始支持generator,就是ES6中会正式定稿的规范。然后就有了基于此特性的koa框架,也就很多人所说的,以更优雅的方式进行流程控制。个人意见,如果没有过多的回调,没有大量的“恶魔金字塔”,还是建议使用Express框架,更易上手,中间件选择更多。接触koa没几天,发现知识点略多略多,逐一击破。
同样是0.11.x后开始原生支持的全局对象,规范与常用的Q模块差异明显,但接口更简化,使用更方便。
假设服务器端请求响应分为三步,加载模板---读取数据---渲染输出。
模板如下(article.jade):
h3| #{title}p| #{content}
数据如下(shuffle.json):
{"title": "love story","content": "No matter what the world will be, never give up for entire life"}
业务代码如下:
fs.readFile(path.join(__dirname, 'views/article.jade'), function(err, data) {if (err) throw err;var template = data.toString();fs.readFile(path.join(__dirname, 'static/shuffle.json'), function(err, data) {if (err) throw err;var local = JSON.parse(data.toString());console.log(jade.compile(template)(local));});});
通过两层回调函数来实现,加载JSON数据可以使用require方式来实现,此处仅为说明情况,因为实际情况下,数据可能来自数据库调用,或者第三方API请求。
这种业务处理方式下,模板与数据存在相互依赖,但不是流程上的顺序并没有严格要求,所以可使用Promise,代码实现如下:
var jadeTemplate = new Promise(function(resolve, reject) {fs.readFile(path.join(__dirname, 'views/article.jade'), function(err, data) {if (err) {reject(err.message);} else {resolve(data.toString());}});});var localData = new Promise(function(resolve, reject) {fs.readFile(path.join(__dirname, 'static/shuffle.json'), function(err, data) {if (err) {reject(err.message);} else {resolve(JSON.parse(data.toString()));}});});Promise.all([jadeTemplate, localData]).then(function(value) {console.log(jade.compile(value[0])(value[1]));});
代码量相对较多,但是效率更好,本机上测试,后者比前者快11ms,所以如有可能,采取后种。
关于generator,所谓的生成器,概念上感觉比较绕口,所以请自行百度。功能上看,就是外部操作控制函数内部代码执行。举一个简单的例子如下:
// yield expressionvar story = function *() {yield 'first step';console.log('first step');yield 'second step';console.log('second step');};var sequence = story();sequence.next();sequence.next();sequence.next();
所谓外部操作控制内部代码执行,可以这么理解。代码从函数内部第‘0’行开始,外部的第一个next方法,开始向下执行,到碰到yield行停止执行。下次外部调用next方法,继续向下执行,知道碰到yield时再次停止,直到内部代码全部执行完毕或者碰到return something(一般不会使用)。每次next方法返回值为一个对象:
{value: anything,done: boolean}
done表示内部代码是否全部执行完毕,即代表是否有进行下一次next方法调用的必要。value值为yield后面跟着的表达式的计算值,可以是字符串,数组,函数等基础类型。
需要说明的是,生成器本身并不是作为流程控制的,但是可以通过二次封装,来实现流程控制,也就是co模块。不折腾,不人生,周末看co模块,好心塞。
QQ:491229492
https://github.com/bornkiller