Node.js res.send VS res.end VS返回res.end

时间:2016-07-06 09:21:35

标签: node.js mongodb express

我有以下代码在mongodb findAndUpdateOne更新查询中有语法错误。

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...

1 个答案:

答案 0 :(得分:7)

首先让我们看看三个ExpressJS功能之间的区别

res.end:来自NodeJS核心。在Express JS中,如果您需要快速结束请求而不需要发送任何数据,那么您可以使用此功能

res.send:发送数据并结束请求

res.json 以JSON格式发送数据并结束请求。

  

我的问题是为什么代码到达代码的最后部分:?

我希望你知道JavaScript是异步语言。使用Mongoose对MongoDB的所有数据库调用都是异步的。所以Compnay.findOne是一个异步函数调用,它保持在事件循环中,直到数据库读操作没有完成。作为JS的异步行为,JS主线程执行不会等待DB函数结果返回(无阻塞)并到达最后一行,并且当你的req以调用res.end("failed")结束时但是当DB读操作时完成后返回数据,然后再次调用res.send并以Error: Can't set headers after they are sent.

结束

希望这会有所帮助:)