如何使我的代码更清晰

该代码用于在Expressjs和MongoDB中处理POST请求

router.post('/', function(req, res){ var data = req.body; Tag.find({name: data.name}).limit(1).exec( function(err, result){ if(err){ } else { if(result.length > 0){ // Already exist a tag with same name res.status(400).end('Already exist!'); } else { // Save the new Tag to database var tag = new Tag(); tag.name = data.name; tag.lastModifier = req.user?req.user.username:"system"; tag.lastModified = Date.now(); tag.save(function(err){ if(err){ res.status(400).json({ message: "insert tag error" }); } else { Tag.findOne(tag, function(err, result){ if(err){ res.status(400).json({ message: "some error.." }); } else { //res.status(400).end('same tag name'); res.status(201).json({ _id: result._id }); } }); } }); } } }); }); 

在最后9行的楼梯是可怕的….请教我如何使这个混乱更清晰?

我真的build议你尝试承诺。 JavaScript和Node.js有许多实现可用。

一个承诺基本上将一个asynchronous操作封装到一个值,它允许你摆脱这些可怕的嵌套callback。 它们还允许您更轻松地链接asynchronous操作。

在基于callback的代码中,你所要做的就是检查每个级别的错误,如果你的error handling可能在一个地方,那么可能会非常乏味。 承诺将传播错误,允许在一个地方轻松处理。

这里有一些参考:

调整使用它们可能需要一些时间,但相信我,这是绝对值得的。

您可以使用命名函数而不是某些函数expression式:

 router.post('/', function(req, res){ var data = req.body; Tag.find({name: data.name}).limit(1).exec( function(err, result){ if(err){ } else { if(result.length > 0){ // Already exist a tag with same name res.status(400).end('Already exist!'); } else { // Save the new Tag to database var tag = new Tag(); tag.name = data.name; tag.lastModifier = req.user?req.user.username:"system"; tag.lastModified = Date.now(); tag.save(save(err)); } } }); }); function save(err){ if(err){ res.status(400).json({ message: "insert tag error" }); } else { Tag.findOne(tag, handleResult(err, result)); } } function handleResult(err, result){ if(err){ res.status(400).json({ message: "some error.." }); } else { //res.status(400).end('same tag name'); res.status(201).json({ _id: result._id }); } } 

(你当然可以将它们命名为更适合这种情况的东西,但它显示了原理。)

 router.post('/', function(req, res){ var data = req.body; Tag.find({name: data.name}).limit(1).exec(cbExec); }); function cbExec(err, result){ if(err){ } else { if(result.length > 0){ // Already exist a tag with same name res.status(400).end('Already exist!'); } else { // Save the new Tag to database var tag = new Tag(); tag.name = data.name; tag.lastModifier = req.user?req.user.username:"system"; tag.lastModified = Date.now(); tag.save(cbSave); } } } function cbSave(err){ if(err){ res.status(400).json({message: "insert tag error"}); } else { Tag.findOne(tag, cbTag); } } function cbTag(err, result){ if(err){ res.status(400).json({message: "some error.."}); } else { //res.status(400).end('same tag name'); res.status(201).json({_id: result._id}); } } 

你可以分开鳕鱼多一点。 而不是创buildlambda函数创build正常的。 if(err){ } else {你可以在第四行中去掉一对大括号

使用if(!err)