2016-07-06 8 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'を呼び出した後のコードは直後に実行され、res.end/sendを送信しないでください。代わりに、あなたがすでに行ったようにコールバックでそれを行います。 –

+0

どのようなmongoose操作でも、コード全体を停止させる方法は 'return res.end'ですか、それとも良い方法ですか? – Trax

+0

戻り値はすべての関数を終了しますが、これはexpressまたはmongooseにとって特別なものではありません。 'res.send'と' end'はクライアントのためのデータを返す関数です。 –

答えて

5

拳3つのExpressJS機能

解像度の違いが何であるかを見ることができます。 end:はNodeJSコアからのものです。エクスプレスJSでは、簡単な方法で要求を終了する必要があり、その後、あなたは、この機能を使用することができ、任意のデータを送信する必要がない場合は

res.send:がデータを送信し、要求に

RESを終了します。 json JSON形式でデータを送信し、要求を終了します。

私の質問は、コードがコードの最後の部分に到達している理由です。

JavaScriptが非同期言語であることをご存じでしょうか? Mongooseを使用するMongoDBへのすべてのデータベース呼び出しは非同期です。したがって、Compnay.findOneは非同期関数呼び出しであり、データベース読取り操作が終了しない限りイベントループにとどまります。 JSの非同期動作として、JSメインスレッドの実行は、DB関数の結果が返される(ノーブロッキング)のを待つことはなく、最後の行に到達し、を呼び出して終了します。 res.sendを呼び出して、あなたはこのことができますError: Can't set headers after they are sent.

希望:)

+0

@Trax 'return res.send()'と 'return res.end()'は同じ効果を持ちます。しかし、私はドキュメンテーションと一緒に行くことを好む:-) –

+0

それはちょっと私の質問だった、なぜ2つが同じ効果を持っていない。 – Trax

関連する問題