在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))
})
})
}
})
})
}
})
})
这甚至不包括错误处理。
我可以做些什么来解开这个烂摊子?
答案 0 :(得分: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))
}
})()
答案 1 :(得分:6)
您可以使用async模块来避免这种情况。
答案 2 :(得分: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))
})
})
代码为here。
此外,nodejs邮件列表中有关于此问题的lengthy discussion。
Step是另一个执行此操作的库。
答案 3 :(得分:1)
请查看Streamline;它是一个JavaScript预处理器,允许您编写简单的“简化”代码并将其转换为回调密码。
答案 4 :(得分:1)
另一种(也许更好)清理此类事情的方法是使用EventEmitters而不是回调。这是一个显示正在使用的几个EventEmitter的示例:
var events = require('events'), util = require('util'); var Search = function () { "use strict"; var search, requestPageData, makeReturnObject, sendResults, emptyObj = {}; events.EventEmitter.call(this); search = function (query) { this.emit("requestPageData", query); }; requestPageData = function (query) { var resultsArray = []; // some logic if (.....some condition....) { this.emit("makeReturnObject", resultsArray); } else { this.emit("sendResults", emptyObj); } }; makeReturnObject = function (resultsArray) { var resultsObj = {}; if (magnetArray) { // some logic this.emit("sendResults", resultsObj); } else { this.emit("sendResults", emptyObj); } }; sendResults = function (obj) { // finally, do whatever it is you want to do with 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();
答案 5 :(得分:0)
您可以使用承诺。看看https://github.com/kriskowal/q