2016-07-06 3 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

функции поиска Mongoose является асинхронной, это означает, что они работают отдельно от основного потока и в фоновом режиме. Код после вызова 'Company.findOne' запускается сразу же после этого, вы не должны res.end/отправлять там. Вместо этого сделайте это на обратном вызове, как вы уже это делали. –

+0

Итак, для любой операции mongoose способ остановить весь код от продолжения - с помощью 'return res.end' или есть лучший способ? – Trax

+0

возвращает концы любой функции, это не что-то особенное для экспресс или мангуста. 'res.send' и' end' - это экспресс-функции для возврата данных для клиента. –

ответ

5

Кулак позволяет увидеть, что разница между тремя ExpressJS функций

Рез. конец: происходит от ядра NodeJS. В экспресс-JS, если вам нужно, чтобы закончить запрос в быстрый способ и не нужно отправлять какие-либо данные, то вы можете использовать эту функцию

res.send: Передает данные и конец данной просьбе

Рез. json Отправляет данные в формате JSON и завершает запрос.

Мой вопрос: почему код достигает последней части кода :?

Надеюсь, вы знаете, что JavaScript является асинхронным языком. Все вызовы базы данных MongoDB с использованием Mongoose являются асинхронными. Таким образом, Compnay.findOne является асинхронным вызовом функции и он остается в цикле событий до тех пор, пока операция чтения базы данных не будет завершена. Поскольку асинхронное поведение JS, выполнение JS Main thread не дожидается возврата результата функции DB (без блокировки) и достижения последних строк, и по мере того, как ваш req заканчивается вызовом res.end("failed") Но когда завершение операции чтения БД возвращает данные, вы снова называя res.send и вы закончили с Error: Can't set headers after they are sent.

Надеется, что это помогает :)

+0

@Trax 'return res.send()' и 'return res.end()' должен иметь такой же эффект. Но я предпочитаю идти с документацией :-) –

+0

Этот вопрос был моим вопросом, почему бы не сделать тот же эффект. – Trax

Смежные вопросы