0

ユーザーオブジェクトを持つmongobがあります。スキーマは次のとおりです。

{
    "_id": {
        "$oid": "50658c835b821298d3000001"
    },
    "email": "admin",
    "password": "admin",
    "id": 1
}

簡単なデモを書きました(主要部分のみ):

function findByEmail(email, callback) {
  db.collection("users", function(err, collection) {
      collection.find({}, function(err, users) {
          users.each(function(err, user) {
              if (user) {
                  if (user.email === email) {
                      //for a case, is we found user - return it
                      callback(null, user);
                  }
              }
          });
          //for a case, is we didn't find user - return null
          callback(null, null);
      });
  });
}

テスト用のルート:

app.get('/test',function(req,res){
  findByEmail("admin", function(err, user){
    res.send(user);
  })
})

localhost:3000/test を起動すると、

Error: Can't set headers after they are sent.

行にコメントcallback(null, null);すると、このエラーは発生しません。コールバックが機能しているようです... 2回!どうしてですか?私がif (user.email === email) { ... }動作し、callback(null, user);起動された場合、関数は にfindbyEmail戻ります<user>app.get、コールバックは が true のcallback(null, null);場合でも 2 回 (また)動作します。if (user.email === email) { ... }

4

3 に答える 3

3

callback(null, null)結果を反復処理した直後に呼び出しています。したがって、いくつかの結果がある場合、-callbackは 2 回呼び出されます。

  • 処理された結果用の 1 つ (出力を送信します)
  • 繰り返しの後の 2 回目。

結果がない場合にのみ呼び出すcallback(null, null)必要があります...

if (!users || users.toArray().length==0) callback(null, null);
于 2012-09-28T20:47:24.297 に答える
0

collection.findに渡す関数とasouterに渡す関数を参照users.eachしてみましょうinner(わかりやすくするために、以下のコードブロックでそのようにラベルを付けています)。ここで問題となるのは、を呼び出すcallback(null, user)innerusers.eachループが引き続き実行され、結果の残りのすべての要素のテストが続行されることです。また、outer関数はまだ終了しておらず、ループが完了callback(null, null)した後にコールバックを呼び出します。以前に提案したように、ユーザーを見つけて呼び出したusers.each直後に呼び出すことはできません。これは、returncallback(null, user)users.eachループして、次の残りのすべての要素に進みます。レコードをすでに見つけたかどうかを示すフラグを定義する必要があります。

collection.find({}, function outer(err, users) {
    var found = false;
    users.each(function inner(err, user) {
        if (user && !found) {
            if (user.email === email) {
                //for a case, is we found user - return it
                callback(null, user);
                found = true;
            }
        }
    });
    //for a case, is we didn't find user - return null
    if (!found) {
        callback(null, null);
    }
});

また、完全にmongoで電子メールを使用してユーザーレコードを検索し、ロジック全体を次のように置き換えることができることにも注意してください。

collection.find({ email: email }, function(err, users) {
    callback(null, users.length? users[0]: null);
});
于 2012-09-29T06:47:55.577 に答える
0

コールバックがまだ実行されます。

for ( var key in obj ) {
  foo();
}

foo();

2 番目の foo() が呼び出されないと予想されるのはなぜですか?

return foo(); を実行する必要があります。続けたくない場合。

于 2012-09-28T21:05:21.373 に答える