如何避免node.js中深层嵌套的代码?

nor*_*gon 9 node.js

在node.js中,它是事件驱动的,所有I/O都是通过回调完成的.所以我最终编写的代码如下所示:

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))
              })
            })
          }
        })
      })
    }
  })
})

这甚至不包括错误处理.

我该怎么做来解开这个烂摊子?

mik*_*obi 6

不要使用匿名函数.

编辑

您的代码甚至无效.您没有关闭大多数函数调用.

如果您切换到命名函数,它将看起来像这样: 更新为反映有关全局命名空间的注释

(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))
    }
})()
Run Code Online (Sandbox Code Playgroud)


Alf*_*red 6

您可以使用异步模块来避免这种情况.


nor*_*gon 5

我写了一个基于node-seq的库,它看起来像这样:

app.get('/test', function (req, res) {
  Seq()
    .seq(function () {
      http.get('some/place', this.next)
    })
    .seq(function (req1, res1) {
      if (res1.statusCode == 200) {
        res1.on('data', this.next)
      }
    })
    .seq(function (data) {
      http.get('other/place?q=' + data, this.next)
    })
    .seq(function (req2, res2) {
      if (res2.statusCode == 200) {
        res2.on('data', this.next)
      }
    })
    .seq(function (data) {
      db.query(data).on('data', this.next)
    })
    .seq(function (rows) {
      res.writeHead(200)
      res.end(JSON.stringify(rows))
    })
})

代码在这里.

此外,有关此问题的nodejs邮件列表上有一个冗长的讨论.

Step是另一个执行此操作的库.