2017-02-25 8 views
0

socket.io関数で、DBに新しいユーザを作成して、挿入されたIDを返します。しかし、私の関数は、データベースコールバックが終了する前に戻ります。だから私は戻って、クライアント側に挿入イドを取得しています:コールバックが終了する前にsocket.io関数が返される - Node.js

io.on('connection',function (socket) { 
    socket.on('newUser',function (user) { 
     io.emit('newUser',createChatRoom(con,user.email,user.phone)); 
    }); 

    }); 

私をユーザー関数を作成します。

var createChatRoom = function (con, email, phone) { 
    con.query("SELECT * FROM USER WHERE `email`='" + email + "'", function (error, result) { 
     if (error) throw error; 
     if (result.length == 0) { 
      var chatToken = require('crypto').createHash('md5').update(email).digest("hex"); 
      con.query("INSERT INTO user(email,chat_token,phone) VALUES('" + email + "','" + chatToken + "','" + phone + "')", function (error1, result1) { 
       return result1.insertId; 
      }); 
     } else { 
      return "Old User"; 
     } 
    }); 
}; 
+0

createChatRoom関数にコールバックを提供し、それをqueryの結果から呼び出します。 – Edgar

答えて

1

では使用できません!

con.queryでデータベースに行っている呼び出しは、「ノンブロッキング」と呼ばれているので、実際にはすぐに終了するとは限りません。

ネットワーク要求は「非ブロック」であり、完了には若干の時間がかかることがあります。それが「ブロック」操作であった場合、プログラムはデータベースからの応答を待つことになります。 JavaScriptの実行をブロックすることはできません。なぜなら、すべてが舞台裏で大きなループで実行されるからです。

これを解決するために、コールバック関数を使用してリクエストを「ノンブロッキング」にします。あなたは実際にすでにそれらを使用しています!私たちが知っている操作に引数としてfunctionを渡すというのは、完了するまでに時間がかかることです。長時間実行される可能性のある操作が終了すると、その結果でコールバック関数が呼び出されます。

コードでは、queryの実行後、指定されたコールバック関数が呼び出されます。

con.query("INSERT INTO user(email,chat_token,phone) VALUES('" + email + "','" + chatToken + "','" + phone + "')", function (error1, result1) { 

あなたの特定の問題を解決するには、あなたのcreateChatRoom関数は、引数としてコールバックを取るようにすることです。

io.on('connection',function (socket) { 
    socket.on('newUser',function (user) { 
    createChatRoom(con, user.email, user.phone, function (error, result1) { 
     if (error) { 
     // hanlde your error 
     // return 
     } 
     io.emit('newUser', result1); 
    }) 
    }); 
}); 

var createChatRoom = function (con, email, phone, callback) { 
    con.query("SELECT * FROM USER WHERE `email`='" + email + "'", function (error, result) { 
    if (error) { 
     return callback(error); 
    } 
    if (result.length == 0) { 
     var chatToken = require('crypto').createHash('md5').update(email).digest("hex"); 
     con.query("INSERT INTO user(email,chat_token,phone) VALUES('" + email + "','" + chatToken + "','" + phone + "')", function (error1, result1) { 
     if (error1) { 
      return callback(error1) 
     } 
     return callback(null, result1.insertId) 
     }); 
    } else { 
     return callback(null, "Old User"); 
    } 
    }); 
}; 

少し変更する必要がありますが、うまくいけばアイデアを得ることができます。

Here's a talk私はトピックとblog postに与えました。

+0

コールバックのためにNode worldで "Error first"というパターンを使用していることを忘れてしまいました。これが意味することは、コールバックへの最初の引数は、1つまたは 'null'がある場合はエラーでなければならないということです。あなたはいつも私のやり方に似たこれらのエラーをチェックするべきです。 – eddiezane

0

更新 io.emitだけでメッセージを表示してイベントを発するので、ソケットの内側にあるcreateChatRoomを呼び出して、io.emitの行をcreateChatRoomの末尾に移動することができます。

io.on('connection',function (socket) { 
    socket.on('newUser',function (user) { 
     createChatRoom(con,user.email,user.phone) 
    }); 
}); 


var createChatRoom = function (con, email, phone) { 
con.query("SELECT * FROM USER WHERE `email`='" + email + "'", function (error, result) { 
    if (error) throw error; 
    if (result.length == 0) { 
     var chatToken = require('crypto').createHash('md5').update(email).digest("hex"); 
     con.query("INSERT INTO user(email,chat_token,phone) VALUES('" + email + "','" + chatToken + "','" + phone + "')", function (error1, result1) { 
      io.emit('newUser',result1.insertId); 
     }); 
    } else { 
     io.emit('newUser',"Old User"); 
    } 
}); 

};

+0

どのようにパラメータを渡すことができますか? –

+0

'socketの内部にコールバックを作成することができます。あなたの変数にアクセスすることができますので、 –

+0

上記のシナリオを使ってサンプルコードを投稿できますか? –

0

Mariaが指摘しているように、newUserハンドラにはnewUserイベントのemitが含まれています。 newUserを発射すると、ハンドラが引き継ぐので、このコードは「循環する」。いくつかのリファクタリングが必要です。一方、createChatRoomはI/Oを持っているので(通常は)遅いです。

NodeJSはnatrueによって非同期です。私がお勧めしたいことは

io.on('connection',function (socket) { 
    socket.on('newUser',function (user) { 
     setImmediate(() => { 
      console.log('Do something (async)'); 
     }); 
     io.emit('newUser',createChatRoom(con,user.email,user.phone)); 
    }); 

    }); 

ノートのように、同期することです:setImmediateあなたは、いくつかの非同期JavaScriptを遭遇したNodeJS < 0.9

+0

私のバージョンはV6.9.2 –

関連する問題