我有以下方法,简化:
var component = require('../../component.js')
exports.bigMethod = function (req, res) {
var connection = new sql.Connection(process.config.sql, function (err) {
new sql.Request(connection)
.input('input', sql.VarChar, 'value')
.execute('dbo.sp1')
.then(function (data) {
if(data[0].length === 0) {
res.status(500).send({ message: 'Some Error' });
}
// set some local variable I'll use later: localVar
new sql.Request(connection)
.input('input1', sql.Int, req.query.input1)
.input('input2', sql.Int, req.query.input2)
.input('input3', sql.DateTime2, req.query.input3)
.input('input4', sql.DateTime2, req.query.input4)
.execute('dbo.sp2')
.then(function (recordset) {
json2csv( { data: recordset[0] }, function(err, data) {
if (err) {
res.status(500).json(err);
}
fs.writeFile(localVar.path, data, function (err) {
if (err) {
res.status(500).json(err);
}
try {
var email = new component.Email();
email.set_callback(function (error) {
if (error) {
res.status(500).send({ message: 'Another error' });
}
res.jsonp([]);
});
email.send(
localVar,
{
filename: localVar.name,
path: localVar.path
}
);
} catch (e) {
res.status(500).send({ message: 'Another Error' });
}
})
});
})
.catch(function (err) {
res.status(500).send({ message: 'Another Error' });
});
})
.catch(function (err) {
res.status(500).send({ message: 'Another Error' });
});
});
};
正如你所看到的,这是一个很长的方法,这是一种反模式。此外,对sp2
的调用实际上是一个重复:还有另一个组件进行类似的调用,只是直接返回json2csv
的结果。
现在,我不太确定如何将此方法划分为充分利用可重用性。我应该在返回Promises的函数中封装数据库调用吗?我应该使用一些咖喱吗?
感谢。
答案 0 :(得分:1)
将代码划分为不同的函数应该是您的top priority - 仅此功能就是处理太多可以轻易划分的事情。
您可以通过分解回调和承诺来使您的代码功能更加清晰,正如您所怀疑的那样。
回调示例:
new sql.Connection(..., handleSQLConnection);
handleSQLConnection(error) { ... }
承诺示例:
doSomething
.then((a) => doOtherStuff(a))
.then((b) => doSmthElse(b));
doOtherStuff(a) { ... }
doSmthElse(b) { ...}
尽管如此,refactoring非常自以为是。但是你应该试着避免上帝的功能,而是编写one thing but they do it well的函数。