2016-11-16 85 views
0

我正在致力于一个经济部门的大学项目。我有很多路线正常工作,但只有这个路线给我造成了很大的问题。Node.js发送后无法设置标题,res.json从未调用过两次

每当这个路线等做响应发送,我收到以下错误:

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

'at /Users/Nasseralwan/Documents/CustExumpSDP/CustomExemptionSystem/controllers/application.js:171:56'你的代码里有什么行? – nicovank

+0

这一个:res.json({ 成功:真, 消息: '创建应用程序', 数据:{请求ID:的applicationID, FactoryID:factoryId } –

+0

你叫'res.end()'后来在这代码? – nicovank

回答

2

像这样的代码是非常难以维持:

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. 

这是第一步,但没有它,你将有一个很艰难的时期确保它所有的作品。

这并不难,你可以自己一步一步做。如果你没有马上看到问题,那么你可以发布另一个问题,但是一个可读的代码将会更有可能得到答案。

相关问题