2016-07-06 79 views
1

我有以下代碼在mongodb findAndUpdateOne更新查詢中有語法錯誤。Node.js res.send VS res.end VS return res.end

router.post('/buylicense', isLoggedIn, function(req, res) { 
    if (!req.body.cid) { 
     return res.send('failed'); 
    } 
    Company.findOne({ 
     ownedBy: req.user.local.username, 
     _id: req.body.cid 
    }, function(err, result) { 
     if (err) { 
      return res.send('failed'); 
     } 
     if (result.license) { 
      return res.send('valid'); 
     } else { 
      Company.findOneAndUpdate({ 
       ownedBy: req.user.local.username, 
       _id: req.body.cid 
      }, { 
       license: true, 
       licenseExpireDate: { 
        $add: ["$date", 3 * 24 * 60 * 60000] // bad code, a problem for another day 
       } 
      }, function(err) { 
       if (err) { 
        console.log(err); 
        return res.end('failed'); // Code should stop here. 
       } 
       console.log('got here'); 
       return res.send('success'); 
      }); 
     } 
    }); 
    console.log('How did I get here?'); 
    res.send('failed'); 
}); 

我的問題是,爲什麼是代碼到達代碼的最後一部分:

console.log('How did I get here?'); 
res.send('failed'); 

如果我用比return res.end以外的任何代碼到達終點和崩潰我的應用程序。簡單地做res.end不起作用,return res.send也不起作用。 return或至少res.end是否足以實際阻止代碼到達最終?

顯示的錯誤,如果我不停止錯誤的right way,可能不相關,但在這裏它是:

How did I get here? 
{ CastError: Cast to date failed for value "[object Object]" at path "licenseExpireDate" 
    at MongooseError.CastError (/media/node_modules/mongoose/lib/error/cast.js:19:11) 
    at SchemaDate.cast (/media/node_modules/mongoose/lib/schema/date.js:242:9) 
    at SchemaDate.castForQuery (/media/node_modules/mongoose/lib/schema/date.js:276:17) 
    at Query._castUpdateVal (/media/node_modules/mongoose/lib/query.js:2477:17) 
    at Query._walkUpdatePath (/media/node_modules/mongoose/lib/query.js:2372:25) 
    at Query._castUpdate (/media/node_modules/mongoose/lib/query.js:2296:23) 
    at castDoc (/media/node_modules/mongoose/lib/query.js:2500:18) 
    at Query._findAndModify (/media/node_modules/mongoose/lib/query.js:1755:17) 
    at Query._findOneAndUpdate (/media/node_modules/mongoose/lib/query.js:1622:8) 
    at /media/node_modules/kareem/index.js:156:8 
    at args (/media/node_modules/kareem/index.js:71:20) 
    at Query.<anonymous> (/media/node_modules/mongoose/lib/schema.js:728:7) 
    at next (/media/node_modules/kareem/index.js:82:14) 
    at Kareem.execPre (/media/node_modules/kareem/index.js:99:3) 
    at Kareem.wrap (/media/node_modules/kareem/index.js:146:8) 
    at Query._findOneAndUpdate (/media/node_modules/kareem/index.js:188:11) 
    message: 'Cast to date failed for value "[object Object]" at path "licenseExpireDate"', 
    name: 'CastError', 
    kind: 'date', 
    value: { '$add': [ '$date', 259200000 ] }, 
    path: 'licenseExpireDate', 
    reason: undefined } 
got here 
_http_outgoing.js:346 
    throw new Error('Can\'t set headers after they are sent.'); 
    ^

Error: Can't set headers after they are sent. 
    at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:346:11) 
    at ServerResponse.header (/media/node_modules/express/lib/response.js:718:10) 
    at ServerResponse.send (/media/node_modules/express/lib/response.js:163:12) 
    at /media/sf_vShared/xyz/app/modalRoutes.js:461:28 
    at /media/node_modules/kareem/index.js:160:11 
    at Query._findAndModify (/media/node_modules/mongoose/lib/query.js:1767:14) 
    at Query._findOneAndUpdate (/media/node_modules/mongoose/lib/query.js:1622:8) 
    at /media/node_modules/kareem/index.js:156:8 
    at args (/media/node_modules/kareem/index.js:71:20) 
    at Query.<anonymous> (/media/node_modules/mongoose/lib/schema.js:728:7) 
    at next (/media/node_modules/kareem/index.js:82:14) 
    at Kareem.execPre (/media/node_modules/kareem/index.js:99:3) 
    at Kareem.wrap (/media/node_modules/kareem/index.js:146:8) 
    at Query._findOneAndUpdate (/media/node_modules/kareem/index.js:188:11) 
    at Query.findOneAndUpdate (/media/node_modules/mongoose/lib/query.js:1611:15) 
    at Function.Model.findOneAndUpdate (/media/node_modules/mongoose/lib/model.js:1491:13) 
[nodemon] app crashed - waiting for file changes before starting... 
+2

貓鼬的查找函數是異步的,這意味着它們在主線程,並在後臺單獨運行結束。在調用'Company.findOne'後的代碼會立即運行,您不應該在此處發送/發送。相反,如你所做的那樣,在回調中做到這一點。 –

+0

因此,對於任何貓鼬操作,停止整個代碼繼續的方式是使用'return res.end'或者有更好的方法嗎? – Trax

+0

返回結束任何功能,這不是特別表達或貓鼬的東西。 'res.send'和'end'是表示函數爲客戶返回數據的函數。 –

回答

5

拳讓我們看看是哪三個ExpressJS功能

資源之間的差異。結束:來自NodeJS核心。在快遞JS如果你需要結束的快捷方式請求,不需要發送任何數據,那麼你可以使用此功能

res.send:發送數據,最終請求

資源。 json以JSON格式發送數據並結束請求。

我的問題是爲什麼代碼到達代碼的最後部分:?

我希望你知道JavaScript是異步語言。所有使用Mongoose的MongoDB數據庫調用都是異步的。所以Compnay.findOne是一個異步函數調用,並且它停留在事件循環中直到數據庫讀取操作未完成。作爲JS的異步行爲,JS主線程執行不會等待DB函數結果返回(無阻塞)併到達最後一行,因爲您的請求以調用res.end("failed")結束。但是當DB讀取操作完成時返回數據,然後再次調用res.send和你Error: Can't set headers after they are sent.

希望這有助於:)

+0

@Trax'return res.send()'和'return res.end()'應該有相同的效果。但我更喜歡用文檔:-) –

+0

這是我的問題,爲什麼不這兩個效果相同。 – Trax