2017-09-15 12 views
1

私は2つのコレクションStudProfを持っています。Nodejs 2つのmongodbコレクションから検索した後の単一のコールバック

私は引数としてidをとり、idがこのコレクションのいずれかに属している場合は、それに応じて情報を返します。

  • まず関数コール:Profコレクション
  • 第二に、関数呼び出しに属しid渡す:Studコレクションに属しているidを渡すことを

期待される結果:最初のProf結果を得る、第二Stud結果。

しかし、nodejsの非同期性のために、私はいつもStudの結果を最初に得て、Profの結果を2番目に得ます。

新しい変数を導入したり、コレクションのクエリ方法を変更したりすることで、このタスクを達成することはできますか?

すべてのヘルプは大幅にあなたが@abdulbarikポストを適用し、この問題からにあなたの質問への答えのために

async.waterfall([ 
    function(callback) { 
     //your fist query method can go here 
     callback(null, query_result1); 
    }, 
    function(first_result1, callback) { 
     // your second query method go here 
     callback(null, query_result2); 
    } 
], function (err, result) { 
    // final result' 
}); 

答えて

3

、このタスクを完了するために、非同期モジュールを使用することができます。ノードの非ブロッキング性を制御する多くの機能があります。ここでは、 "並列"メソッドを使用することをお勧めします。クエリは互いに独立しているため、「滝」メソッドよりも高速になります。

ご質問によると、コードは次のようになります。

var async = require('async'); 

async.parallel([ 
    cb=>{ 

     Stud.findOne({ 
     '_id': userid 
     },cb); 
    }, 
    cb=>{ 

     Prof.findOne({ 
     '_id': userid 
     },cb); 

    } 
],(err,result)=>{ 
     if(err) { 
      //handle error 
      return; 
     } 

      //result will be an array where the first element will be the result of first query and 
      // second element will be the query result for the second query 
      // so according to this ..... 

     if(result[0]){ 
      //id is matched with Stud collection 
      //result[0] is the student doc 
     }else if(result[1]) { 
      //id is matched with Prof collection 
      //result[0] is the professor doc 
     }else { 
      //Neither Stud or Prof 
     } 
}); 

あなたは** asyn documentation

1

を理解されるであろう。


  • あなたはコールバックを使用している場合は、適切にエラーを返すためにそれらを使用し、機能
  • にあなたの要求をカット:ここ

    は、あなたの実際のコードについて、他のものがあります。捨てないで。ので、あなたが今ES6をサポートNode.jsのを(そのほとんど)、それを使用使用しているの

    • あなたは引用符に

    備考_idキーを配置する必要はありません。読みやすく、効率的です。


コールバックや機能カットについてのサンプル。私はあなたがes6、滝の扱いである残りのことをさせる...あなたはPromiseとAsync/Awaitパターンthoを見ることができます。

:あなたが約束して、コードの例

check_user_info(user_id, function (err, result) { 
    // ... 
}); 

それを呼び出す方法

// Check if there is a student 
function check_student(user_id, callback) { 
    Stud.findOne({ 
    _id: user_id 
    }, function (err, stud) { 
    if (err) return callback(err, false); 

    // stud here can worth false 
    return callback(false, stud); 
    }); 
} 

// Check if there is a prof 
function check_prof(user_id, callback) { 
    Prof.findOne({ 
    _id: user_id 
    }, function (err, prof) { 
    if (err) return callback(err, false); 

    // prof here can worth false 
    return callback(false, prof); 
    }); 
} 

// Get Stud not Prof info 
function check_user_info(user_id, callback) { 
    // Look if user_id match a stud 
    check_student(user_id, function (err, result) { 
    // We have an error 
    if (err) return callback(err, false); 

    // We have a student 
    if (result) return callback(false, result); 

    // Check if user_id match a prof 
    check_prof(user_id, function (err, result) { 
     // We have an error 
     if (err) return callback(err, false); 

     // We have a prof 
     if (result) return callback(false, result); 

     // No result at all 
     return callback(false, false); 
    }); 
    }); 
} 

前の回答として

 // Check if there is a student 
     function check_student(user_id) { 
      return new Promise((resolve, reject) => { 
      Stud.findOne({ 
       _id: user_id 
      }, (err, stud) => { 
       if (err) return reject(err); 

       // prof here can worth false 
       return resolve(stud); 
      }); 
      }); 
     } 

     // Check if there is a prof 
     function check_prof(user_id) { 
      return new Promise((resolve, reject) => { 
      Prof.findOne({ 
       _id: user_id 
      }, (err, prof) => { 
       if (err) return reject(err); 

       // prof here can worth false 
       return resolve(prof); 
      }); 
      }); 
     } 

     // Get Stud not Prof info 
     function check_user_info(user_id) { 
      return Promise.all([ 
      check_student(user_id), 
      check_prof(user_id), 
      ]); 
     } 

check_user_info(user_id) 
    .then([ 
    stud, 
    prof, 
    ] => { 
    // Handle result 
    }) 
    .catch((err) => { 
    // Handle error 
    }); 
1

async muduleのwaterfall方法を使用することができます

var check_user_info = function(userid, callback) { 
    Stud.findOne({ 
     '_id': userid 
    }, function(err, stud) { 
     if (err) 
      throw err 
     if (stud) { 
      callback(stud); 
     } else { 
      Prof.findOne({ 
       '_id': userid 
      }, function(err, prof) { 
       if (err) 
        throw err 
       if (prof) { 
        callback(prof); 
       } else { 
        callback(false); 
       } 
      }) 
     } 
    }) 
    return 
} 
+1

から非同期メソッドについて**コードに修正を行うための感謝を読むことができます。私はあなたが説明した方法を感謝しますが、@ Shawon –

関連する問題