質問: "SELECT count(*) as cnt FROM hogehoge"; new mssql.Request().query(sql).then(function(results) { if(results.length > 0){ return results[0].cnt; } }).catch(function(err) { console.log(err); }); }); } ``` おわかりの方がいらっしゃいましたらご教示お願いします。
回答: Promiseを使った非同期処理なので、returnで返すことはできません。 countを使う関数をコールバック関数として渡しておく、 Promiseを自体を返して、thenの中で処理をするなどといった処理を書く必要があります。 Promise自体の説明はここでは無理ですが、簡単に何が起きているか書くと、 countのfunctionが呼ばれた時、connection.thenは非同期で実行される(ブロックされない)のでcount関数はthenの行をすぐにぬけてなにもreturnしないままに終了しています。 その後(count関数の実行が終わった後)、connection.thenの中のfunctionは、connectionの非同期処理が終わった後に呼ばれています。 コールバックの方のコードを示しておきます。 ``` // コールバック関数を用意する var myCallback = function(count){ // カウントが取れたら実行したいこと } // コールバックを渡しておく var count = function(myCallback) { connection.then(function(){ sql = "SELECT count(*) as cnt FROM hogehoge"; new mssql.Request().query(sql).then(function(results) { if(results.length > 0){ // コールバックを呼ぶ myCallback( results[0].cnt ); } }).catch(function(err) { console.log(err); }); }); } ``` ちょっと余談ですが、Promiseをreturnすればthenで順次解決していくことができますので、 元のコードは以下の様にできそうに思います(すいませんが、実際に動かしてないので) ``` var count = function() { connection.then(function(){ sql = "SELECT count(*) as cnt FROM hogehoge"; // ここで queryもPromiseを返している様なので、 returnしてしまう。 return new mssql.Request().query(sql); }) .then(function(results) { // queryが終わったら実行される if(results.length > 0){ // results[0].cnt を使った処理を書く } }) .catch(function(err) { // このcatchはconnectionの失敗でも取れると思います console.log(err); }); } ``` 本当は、queryのthenの中で自分でPromise作って・・・などもできるんですが、 ここで説明しきれる内容ではないので割愛します。