我正在为一个经济部门的大学项目工作。我有很多路线正常工作,但只有这个路线给我造成了很大的问题。
无论何时完成此路由并发送响应,我都会收到以下错误:
Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:346:11)
at ServerResponse.header (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/express/lib/response.js:719:10)
at ServerResponse.send (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/express/lib/response.js:164:12)
at ServerResponse.json (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/express/lib/response.js:250:15)
at /Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/controllers/application.js:171:56
at Query._callback (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/models/application.js:141:25)
at Query.Sequence.end (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/mysql/lib/protocol/sequences/Sequence.js:85:24)
at Query._handleFinalResultPacket (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/mysql/lib/protocol/sequences/Query.js:144:8)
at Query.OkPacket (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/mysql/lib/protocol/sequences/Query.js:78:10)
at Protocol._parsePacket (/Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/node_modules/mysql/lib/protocol/Protocol.js:280:23)
以下是此路线调用的功能:
registerFactory: function (req, res ) {
var userDetails = req.user;
var requestData = req.body;
var hscode = "NULL";
var applicationID = "FR";
var applicationType = "Factory";
var factoryId = "";
if (userDetails.usergroup == "Client") {
var d = new Date();
var year = d.getFullYear();
applicationID = applicationID + year;
var dnum = 5;
var num = 0;
applicationModel.getLastAppID(applicationType, function (err, results) {
if (err) {
return res.json({success: false, message: 'Database Error. '});
}else{
num = results[0].LastID;
console.log(num);
dnum = dnum - num.toString().length;
while (dnum != 0) {
applicationID = applicationID + "0";
dnum = dnum - 1;
}
applicationID = applicationID + num;
num = num + 1;
applicationModel.updateLastAppID(num, applicationType, function (err) {
if (err) {
return res.json({success: false, message: 'Database Error. '});
}else{
factoryController.registerFactory(userDetails,requestData, function (err,FID) {
if (err) {
return res.json({success: false, message: 'Database Error. '});
}else{
factoryId = FID;
applicationModel.createFactoryRegApplication(userDetails, requestData, applicationType, applicationID,hscode, function (err) {
if (err) {
return res.json({success: false, message: 'Database Error. '});
} else {
res.json({
success: true,
message: 'Application Created',
data: {RequestID: applicationID,
FactoryID : factoryId
}
});
}
});
}
});
}
});
}
});
} else {
return res.json({success: false, message: 'unauthorized Access'});
}
}
我不知道为什么会发生这种情况,即使res.json永远不会被调用两次。
答案 0 :(得分:3)
这样的代码非常难以维护:
http://icompile.eladkarako.com/wp-content/uploads/2016/01/icompile.eladkarako.com_callback_hell.gif
它甚至不适合在屏幕上显示,所以我很难阅读它。我可以给你一些关于如何重构它以使其易于管理的一般性建议。希望这将有助于您解决此问题以及将来类似的问题。
首先,取每个匿名函数并将其更改为命名函数。所以,当你有:
applicationModel.updateLastAppID(num, applicationType, function (err) {
// ...
});
将其更改为:
applicationModel.updateLastAppID(num, applicationType, updatedLastAppID);
function updatedLastAppID(err) {
// ...
}
使用您拥有的每个function
执行此操作。仅此一项可能会向您展示您的问题,因为您将拥有一个易于阅读和理解的自编档文,因为:
例如:
applicationModel.updateLastAppID(num, applicationType, function (err) {
if (err) {
return res.json({success: false, message: 'Database Error. '});
}else{
factoryController.registerFactory(userDetails,requestData, function (err,FID) {
if (err) {
return res.json({success: false, message: 'Database Error. '});
}else{
factoryId = FID;
applicationModel.createFactoryRegApplication(userDetails, requestData, applicationType, applicationID,hscode, function (err) {
if (err) {
return res.json({success: false, message: 'Database Error. '});
} else {
res.json({
success: true,
message: 'Application Created',
data: {RequestID: applicationID,
FactoryID : factoryId
}
});
}
});
}
});
}
});
将改为:
applicationModel.updateLastAppID(num, applicationType, updatedID);
function updatedID(err) {
if (err) {
return res.json({success: false, message: 'Database Error. '});
} else {
factoryController.registerFactory(userDetails, requestData, factoryRegistered);
}
}
// etc.
这是第一步,但如果没有它,你将很难确保一切正常。
这并不难,你可以自己一步一步做。如果您没有立即看到问题,那么您可以发布另一个问题,但使用可读的代码,您将更有可能获得答案。