Node.JS
十个Node.js开发易犯错误之五:创建大型整体单片monolithic应用
Node开发新手可能来自于不同的各种语言,他们做事的风格不同,经常喜欢将每件事放入一个文件中,或者不将长代码切分到模块发布到NPM中。
以我们先前的案例为说明,我们已经将每个功能都放入了一个文件,这难于测试和阅读,但是不要担心,经过稍微的重构以后我们能够使其更好和更模块化,这也有助于克服回调地狱的问题。
如果我们释放URL校验器,响应处理器,请求函数和资源处理器到不同的文件中,那么我们的主程序代码就如下:
......
var handleBadResponse = require('./lib/bad-response-handler'); var isValidUrl = require('./lib/url-validator'); var extractResources = require('./lib/resource-extractor'); var request = require('./lib/requester'); ....
async.series([ function getRootHtml(cb) { request(URL, function(err, data) { if (err) { return cb(err); }
rootHtml = data.body;
cb(null, 123); }); }, function aggregateResources(cb) { resources = extractResources(rootHtml);
setImmediate(cb); }, function calculateSize(cb) { async.each(resources, function(relativeUrl, next) { var resourceUrl = url.resolve(URL, relativeUrl);
request(resourceUrl, function(err, data) { if (err) { return next(err); }
if (data.res.headers['content-length']) { totalSize += parseInt(data.res.headers['content-length'], 10); } else { totalSize += Buffer.byteLength(data.body, 'utf8'); }
next(); }); }, cb); } ], function(err) { if (err) { throw err; }
var size = (totalSize / 1024 / 1024).toFixed(2); console.log('\nThere are ~ %s resources with a size of %s Mb.', resources.length, size); }); |
请求函数被装入文件lib目录下的request.js中,其代码如下:
var handleBadResponse = require('./bad-response-handler'); var request = require('request');
module.exports = function getSiteData(url, callback) { request({ url: url, gzip: true, // lying a bit headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.111 Safari/537.36' } }, function(err, res, body) { if (handleBadResponse(err, url, res && res.statusCode, callback)) { return; }
callback(null, { body: body, res: res }); }); };
|
这些函数代码都切割到lib目录下的不同的文件中,见Github
现在事情变得简单多了,我们能够易于测试和阅读。Node鼓励你编写小模块并发布到NPM中,你会发现那里有很多各种不同的库包,你能够在你的应用中尽情地使用这些包,让事情变得更加坚定。有关如何编写模块见:the one