如何避免在node.js中深度嵌套的代码?
在node.js中,它是事件驱动的,所有的I / O都是通过callback来完成的。 所以我最终编写的代码如下所示:
app.get('/test', function (req, res) { http.get('some/place', function (req1, res1) { if (res1.statusCode == 200) { res1.on('data', function (data) { http.get('other/place?q=' + data, function (req2, res2) { if (res2.statusCode == 200) { res2.on('data', function (data) { db.query(data).on('data', function (rows) { res.writeHead(200) res.end(JSON.stringify(rows)) }) }) } }) }) } }) })
这甚至不包括error handling。
我能做些什么来放松这个混乱?
你可以使用asynchronous模块来避免这种情况。
不要使用匿名函数。
编辑
你的代码甚至不是有效的。 你没有closures大部分的函数调用。
如果你切换到命名函数,它会看起来像这样: 更新反映关于全局命名空间的评论
(function () { app.get('/test', f0) function f0(req, res) { http.get('some/place', f1) } function f1(req1, res1) { if (res1.statusCode == 200) { res1.on('data', f2) } } function f2(data) { http.get('other/place?q=' + data, f3) } function f3(req2, res2) { if (res2.statusCode == 200) { res2.on('data', f4) } } function f4(data) { db.query(data).on('data', f5) } function f5(rows) { res.writeHead(200) res.end(JSON.stringify(rows)) } })()
我写了一个基于node-seq的库,如下所示:
app.get('/ test',function(req,res){ SEQ() .seq(function(){ http.get('some / place',this.next) }) .seq(function(req1,res1){ 如果(res1.statusCode == 200){ res1.on('data',this.next) } }) .seq(function(data){ http.get('other / place?q ='+ data,this.next) }) .seq(function(req2,res2){ 如果(res2.statusCode == 200){ res2.on('data',this.next) } }) .seq(function(data){ db.query(data).on('data',this.next) }) .seq(函数(行){ res.writeHead(200) res.end(JSON.stringify(行)) }) })
代码在这里 。
另外,关于这个问题,关于nodejs邮件列表还有很长的讨论 。
步骤是另一个库做这个东西。
请看Streamline ; 它是一个JavaScript预处理程序,允许您编写简单的“简化”代码并将其转换为callback代码。
另一个(也许更好的)清理这种事情的方法是使用EventEmitter而不是callback。 以下是一个显示使用中的几个EventEmitter的例子:
var events = require('events'), util = require('util'); var Search = function(){ “严格使用”; varsearch, requestPageData, makeReturnObject, sendResults, emptyObj = {}; events.EventEmitter.call(本); search = function(query){ this.emit(“requestPageData”,查询); }; requestPageData =函数(查询){ var resultsArray = []; //一些逻辑 如果(.....有些情况....){ this.emit(“makeReturnObject”,resultsArray); } else { this.emit(“sendResults”,emptyObj); } }; makeReturnObject = function(resultsArray){ var resultsObj = {}; if(magnetArray){ //一些逻辑 this.emit(“sendResults”,resultsObj); } else { this.emit(“sendResults”,emptyObj); } }; sendResults = function(obj){ //最后,做任何你想用obj做的事情 }; this.on(“requestPageData”,requestPageData); this.on(“makeReturnObject”,makeReturnObject); this.on(“sendResults”,sendResults); this.search = search; }; util.inherits(Search,events.EventEmitter); module.exports = new Search();
你可以使用promise。 看看这个https://github.com/kriskowal/q