2016-07-24 14 views
0

我的腳本檢查數據庫中是否存在標識。如果沒有,它應該停止在那裏然後邏輯。如果文檔未找到,停止響應

但是,目前發生的是不是返回「提供的項目ID不存在於我們的數據庫中」,它返回「請發送所有需要的細節。」。 (大概是因爲第一回帶我們離開功能)

var projectExists = function(pId, callback) { 
    ProjectsData.count({project_id: pId}, function(err, doc) { 

     if (err) { 
      throw err; 
     } 
     callback(doc); 
    }); 
}; 

// Create a new Game ID. 
v1.post("/", function(req, res, next) { 

    if (!("project_id" in req.body)) { 
     return res.send("You need to provide Project ID"); 
    } 

    // Check if the Project ID is in the file. 
    // Problematic bit 
    projectExists(req.body.project_id, function(c) { 
     if (c == 0) { 
      return res.send("The provided Project Id does not exist in our database."); 
     } 
    }); 

    var gameDataObj = req.body; 

    GameData.addGameId(gameDataObj, function (err, doc) { 
     if (err) { 
      if (err.name == "ValidationError") { 
       return res.send("Please send all the required details."); 
      } 
      throw err; 
     }; 

     res.json(doc); 
    }) 
}); 

我在做什麼錯?有沒有更好的方法來做到這一點?


而後續問題;在當前迭代中,如果ID是錯的也有這樣的錯誤:

Error: Can't set headers after they are sent. 
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:344:11) 
    at ServerResponse.header (G:\node\vnlytics\node_modules\express\lib\response.js:719:10) 
    at ServerResponse.send (G:\node\vnlytics\node_modules\express\lib\response.js:164:12) 
    at G:\node\vnlytics\controllers\v1\game.data.js:35:17 
    at G:\node\vnlytics\controllers\v1\game.data.js:20:9 
    at Query.<anonymous> (G:\node\vnlytics\node_modules\mongoose\lib\model.js:3331:16) 
    at G:\node\vnlytics\node_modules\kareem\index.js:259:21 
    at G:\node\vnlytics\node_modules\kareem\index.js:127:16 
    at nextTickCallbackWith0Args (node.js:420:9) 
    at process._tickCallback (node.js:349:13) 

這可能是因爲我們派出兩個響應,但有什麼奇怪的是,檢查res.headersSent直到最後一刻返回false。

+1

您需要對異步操作進行排序。在進入下一個之前,您並沒有等待第一個異步操作完成。因此,它們最終都會並行運行,並且當它們全部結束時,最終會嘗試發送多個響應(從而導致出現錯誤)。 – jfriend00

+0

好的。我查了一下,好像我也可以用Promise做到這一點,對吧? – DragoonHP

+0

通常這意味着錯誤處理不正確。你是否嘗試過使用next(err)而不是throw err,並檢查錯誤處理程序到底發生了什麼? –

回答

1

正如我在我的評論中所說的,您需要正確地對異步操作進行排序,以便在知道前一個結果並處理結果之前不要開始下一個異步操作。你可以這樣做:

// Create a new Game ID. 
v1.post("/", function(req, res, next) { 

    if (!("project_id" in req.body)) { 
     return res.send("You need to provide Project ID"); 
    } 

    // Check if the Project ID is in the file. 
    // Problematic bit 
    projectExists(req.body.project_id, function(c) { 
     if (c == 0) { 
      return res.send("The provided Project Id does not exist in our database."); 
     } else { 
      var gameDataObj = req.body; 

      GameData.addGameId(gameDataObj, function (err, doc) { 
       if (err) { 
        if (err.name == "ValidationError") { 
         return res.send("Please send all the required details."); 
        } 
        throw err; 
       }; 

       res.json(doc); 
      }) 
     } 
    }); 

}); 

P.S.您應該更換throw err並進行適當的錯誤處理。你需要在這裏發送一個錯誤響應。 throw不會做任何有用的事情,除非停止處理,否則從未發送響應。

+0

非常感謝。我無法相信我所要做的就是添加一個else塊。至少我現在知道貓鼬支持承諾。非常感謝您的幫助。 – DragoonHP

+0

@DragoonHP - 爲了記錄,用承諾做這件事會更好。對於序列化操作你會得到更乾淨的代碼,並且通常良好的錯誤處理要容易得多。 – jfriend00