如何避免在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