0

我在使用 node.js 时遇到问题,每次运行查询时,它都会重新运行以前运行的所有查询以及新的查询。

更具体地说:我有一个包含三个字段的表单:名字、姓氏、电子邮件。当我提交该表单时,我想: - 检查用户是否已经存在于数据库中(我通过对电子邮件地址的 SQL 查询来执行此操作)。- 如果客户端存在,则在表单上显示无法添加客户端的消息。- 如果用户不存在,将客户端添加到数据库并在表单上显示“成功添加客户端”消息。

看起来很容易,对吧?

发生的事情是,对于我添加的第一个新用户,一切都很好。然后我添加了第二个新用户,但在数据库中发生的情况是它添加了两个条目:它重新添加了第一个新用户,以及第二个新用户。如果我尝试添加第三个用户,它最终会运行 3 个“INSERT INTO”查询,添加第一个用户(第三次)和第二个用户,然后是第三个。等等...

就像在表单提交之间我没有清除某些存储空间 - 但我没有在这里使用会话,所以我不知道这些表单数据被保存在哪里!

有什么想法吗?我对 node.js 很陌生,我想我一定错过了一些非常基本的东西,但我看不到它。

这是我的“index.html”文件中的 javascript 和表单:

<script type="text/javascript"> 
    $(document).ready(function(){
        $("#new_client").submit(function(){
            var form = $(this);

            //remove previous message section
            form.siblings('p').remove();

            $.getJSON(
                form.attr('action'),
                form.serialize(),
                function (result){
                    if (result.success == true){
                        $(form).before("<p>Success: "+result.message+"</p>");
                    }
                    else if (result.success == false){
                        var html = "";
                        for (var i = 0; i < result.message.length; i++){
                            html += "<p>Failed: "+result.message[i]+"</p>";
                        }
                        $(form).before(html);
                    } 
                }); //end $.getJSON

             return false;
        });
    });
</script>

<body>
    <form id="new_client" action="/add_client" method="get">
    <!-- NOTE: we need to use method="get" for getJSON -->
        <input type="text" name="first_name" placeholder="Client first name">
        <input type="text" name="last_name" placeholder="Client last name">
        <input type="text" name="email" placeholder="Client email">
        <button type="submit">Add Client</button>
    </form>
</body>

以下是我的 nodejs 代码(server.js)的一部分:

var http = require('http');
var url = require('url');
var path = require('path');
var fs = require('fs');
var querystring = require('querystring');
var mysql = require('mysql');
var events = require('events');
var Validator = require('validator').Validator;
var eventEmitter = new events.EventEmitter();

var db = mysql.createConnection({
   //host:'localhost',
   port: 8889,
   user: 'root',
   password: 'root',
   database: 'test_database'
});

server = http.createServer(function (request, response){
var pageUrl = url.parse(request.url).pathname;

if(pageUrl === '/add_client'){
    var dataQuery = url.parse(request.url).query;
    var formData = querystring.parse(dataQuery);

    //set up event listener for 'add client result'
    eventEmitter.on('addClientResult', function (result){
        response.end(JSON.stringify(result));
    });

        //set up listener for existing client check
        eventEmitter.on('clientIsNewResult', function (result){
            if (result.success === false){
            response.end(JSON.stringify(result));
            }
            else {
                //this will trigger the 'addClientResult' event
                addClient(db, formData.first_name, formData.last_name, formData.email);
            }
        });

        //set up event listener for validated data
        eventEmitter.on('validateDataResult', function (result){
            if (result.success === false)
                response.end(JSON.stringify(result));
            else{
                //trigger 'clientIsNewResult' event
                clientIsNew(db, formData.email);
            }
        });

        // trigger the validateDataResult event
        validateData(formData.first_name, formData.last_name, formData.email);

    } //end 'add_client'
    else { ... code for other actions and where we start the response object... }
}); //end of server object

server.listen(8080);

function clientIsNew(db, email){
    db.query('SELECT * FROM clients WHERE email=?', [email],
        function (errors, results, fields) {
            if (errors) throw errors;

                //console.log(this.sql);
                if (results.length > 0){
                    query_result = {
                        'success': false,
                        'message': ['There is already a client with this email address!']
                }
            }
            else {
                query_result = {
                    'success': true,
                    'message': 'This is a unique user'
                };
            }

            eventEmitter.emit('clientIsNewResult', query_result);
    });
}
function addClient(db, first_name, last_name, email){
    //the only time we should get here is when we want to create a new user
    //so we should only get here when 'clientIsNewResult' is triggered and gets
    // a result of true... at least that is the intention!
    db.query('INSERT INTO clients SET first_name=?, last_name=?, email=?, created_at=NOW();',
        [first_name, last_name, email],
        function (errors, results, fields) {
            if (errors) throw errors;

            //console.log(this.sql);
            insert_result = {
                'success': true,
                'message': 'Client is added'
            }

            eventEmitter.emit('addClientResult', insert_result);
        }
    );
}

function validateData(first_name, last_name, email){
... validates info, no problems with this ...

    eventEmitter.emit('validateDataResult', result);
}

console.log('Server running at http://localhost:8080/');

好的,我希望这不是太多,我也删除了很多评论和其他 console.log 行。

如果我需要发布更多或更少,或者我忘记了什么,请告诉我。

在此先感谢您的帮助!

4

2 回答 2

0

将您的事件发射器移动到您的 http 请求内部

移动

var eventEmitter = new events.EventEmitter();

server = http.createServer(function (request, response){
var pageUrl = url.parse(request.url).pathname;
var eventEmitter = new events.EventEmitter();
于 2013-07-30T20:26:17.117 回答
0

终于得到了导师的指导。我的问题是每次向服务器发送数据时,我都会创建另一个事件侦听器,但之前的事件侦听器仍然存在。所以我第二次提交表单时,同一个事件有两个事件监听器;第三次,有三个……等等。

解决方案:主要重构代码,不要使用这么多。另外:更改eventEmitter.on()eventEmitter.once()addClientResult 事件,这是唯一剩下的事件侦听器。毕竟,我只想在每次向服务器提交数据时添加一次客户端。

于 2013-08-02T03:40:54.130 回答