【问题标题】:MySQL callbacks and scopeMySQL 回调和范围
【发布时间】:2014-01-11 06:38:27
【问题描述】:

我在使用 node-mysql 构建使用 express 的 Web API 时遇到问题。我有以下文件./lib/handlers/list.js,它已加载并且一切正常(使用require('./lib/handlers/list.js')(app)):

var error= function(res){
  res.json([]);
}

var send_lists = function(res,lists){
    res.json(lists);
}

var add_tasks_to_lists = function(res,lists){
    for (var i = 0, list; i < lists.length, list=lists[i]; i++) {
        var connect=require('../../mysql.js').connection();
            connect.connect();
            connect.query("SELECT * FROM `www`.`teamli_tasks` WHERE `list_id`="+connect.escape(list['id'])+";",function(_err,_rows){
              if(!_err && _rows && _rows.length){
                var tasks=[];
                for(var j=0, _row; j < _rows.length, _row=_rows[j], _row!=null; j++){
                  var task={};
                  task['id']=_row.id;
                  task['text']=_row.text;
                  task['completed']=_row.completion?true:false;
                  tasks.push(task);
                }
                list['tasks']=tasks;
              }
            });
    }
    send_lists(res,lists);
}

module.exports = function(app){
  app.post('/api/list',function(req,res){
    console.log(req.session);
    if(req.hasOwnProperty("body") && req.body && req.hasOwnProperty("session") && req.session && req.session.hasOwnProperty("user") && req.session.user && req.session.user.hasOwnProperty("id") && req.session.user.id){
      var connection=require('../../mysql.js').connection();
      connection.connect();
      connection.query("SELECT * FROM `www`.`teamli_lists` WHERE `owner_id`="+connection.escape(req.session.user.id)+";",function(err, rows){
        if(!err && rows && rows.length){
          var lists=[];
          for (var i = 0, row; i < rows.length, row=rows[i]; i++) {
            console.log("Getting list with ID: "+row.id);
            var list={};
            list['participants']=req.session.user.username;
            list['timeenforcer']=null;
            list['id']=row.id;
            list['date']=1382659200;
            list['duedate']=null;
            list['title']=row.name;
            list['color']=row.color;
            console.log(list);
            lists.push(list);
          }
        add_tasks_to_lists(res,lists);
        }else error(res);
      });
    }else error(res);
  });
}

然而,当这个 API 端点被命中 (/api/list) 时,我得到这个错误:

TypeError: Cannot set property 'tasks' of undefined
    at Query._callback (/var/www/main/www/lib/handlers/api/list.js:24:27)

require('../../mysql.js').connection() 产生一个新的node-mysql Connection 对象,使用 mysql.js 中提供的凭据进行设置。 teamli_lists 和 teamli_tasks 里面都有相关数据,通过id/list_id连接。

我对 Node 有点陌生,尤其是像这样的异步东西,所以感谢任何帮助。如果您需要更多信息,请告诉我。谢谢!

【问题讨论】:

标签: mysql json node.js api express


【解决方案1】:

我设法让它正常工作 - 我知道,我仍然需要释放连接,并整理代码,但现在可以:

var lists=[];
var lists_count;

var error= function(res){
  res.json([]);
}

var send_lists = function(res,lists){
    res.json(lists);
}

var add_list = function(res,list){
    lists.push(list);
    if(lists.length==lists_count) send_lists(res,lists);
}

var add_tasks_to_list = function(res,list,callback){
    console.log("Adding task to list: "+list);
        var connect=require('../../mysql.js').connection();
            connect.connect();
            connect.query("SELECT * FROM `www`.`teamli_tasks` WHERE `list_id`="+connect.escape(list['id'])+";",function(_err,_rows){
              if(!_err && _rows && _rows.length){
                var tasks=[];
                for(var j=0, _row; j < _rows.length, _row=_rows[j], _row!=null; j++){
                  var task={};
                  task['id']=_row.id;
                  task['text']=_row.text;
                  task['completed']=_row.completion?true:false;
                  tasks.push(task);
                }
                list['tasks']=tasks;
              }
                callback(res,list);
            });
}

module.exports = function(app){
  app.post('/api/list',function(req,res){
    console.log(req.session);
    if(req.hasOwnProperty("body") && req.body && req.hasOwnProperty("session") && req.session && req.session.hasOwnProperty("user") && req.session.user && req.session.user.hasOwnProperty("id") && req.session.user.id){
      var connection=require('../../mysql.js').connection();
      connection.connect();
      connection.query("SELECT * FROM `www`.`teamli_lists` WHERE `owner_id`="+connection.escape(req.session.user.id)+";",function(err, rows){
        if(!err && rows && rows.length){
            lists_count=rows.length;
          for (var i = 0, row; i < rows.length, row=rows[i]; i++) {
            console.log("Getting list with ID: "+row.id);
            var list={};
            list['participants']=req.session.user.username;
            list['timeenforcer']=null;
            list['id']=row.id;
            list['date']=1382659200;
            list['duedate']=null;
            list['title']=row.name;
            list['color']=row.color;
            add_tasks_to_list(res,list,add_list);
          }
        }else error(res);
      });
    }else error(res);
  });
}

【讨论】:

  • 谢谢大家的帮助。
【解决方案2】:

错误表明属性“任务”正在用于未定义的变量。您尝试设置“任务”属性的位置在这里:

list['tasks']=tasks;

但是在 for 循环中声明时,您的列表永远不会被初始化。试试list = {};(一个空对象)

【讨论】:

  • 相反,我的循环定义为for (var i = 0, list; i &lt; lists.length, list=lists[i]; i++),所以list应该设置为lists[i],不是吗?
  • 我错过了,虽然不能确定将它放在那里时会发生什么。我一直使用 for 循环的第二条语句作为循环运行的条件,而不是“在下一次执行之前运行的代码”。也许尝试将 list = lists[i] 放在 for 循环中?我只能看到“tasks”属性使用过一次,如果错误是关于未分配的变量,那么我们需要确保它已被分配。
  • 我解决了这个问题,但现在代码似乎没有在发送列表之前添加任务(可能是因为对 send_lists 的调用在异步(?) MySQL 代码之外)。我想也许我应该检查 i==lists.length,但在任务添加完成之前仍然会调用它。
  • 正确,send_lists() 调用应该在function(err, rows) 内部,因为 被异步调用的。所以你只想在完成后发送。
  • 如果这是答案,您应该选择它作为答案。
猜你喜欢
  • 1970-01-01
  • 2015-02-05
  • 1970-01-01
  • 1970-01-01
  • 2011-03-22
  • 1970-01-01
  • 1970-01-01
  • 2013-11-30
  • 1970-01-01
相关资源
最近更新 更多