【问题标题】:MySQL problems in Node.js - fetch all queryNode.js 中的 MySQL 问题 - 获取所有查询
【发布时间】:2015-11-14 16:59:56
【问题描述】:

我在 Node.js 中有一个问题,我已经构建了自己的模块来处理某种东西,在这个模块中我有一个函数 getList(),我可以在其中获取我的配置的输入。

我的源代码是这样的:

var config = {
    'limit' : 0
};

var dict = [];


exports.getList = function(db, conf) {
    db.query("SELECT id, title FROM animal a " + (config.limit > 0 ? " LIMIT " + config.limit : "" ), function(err, rows, fields) {
        if(err) {
            console.log(err);
        }

        for(var key in rows) {
                var row = rows[key];
        //
                dict.push({
                    'title' : 'Buster',
                    'animal' : 'Dog',
                    'age' : '12',
                    'photo' : 'https://placeholdit.imgix.net/~text?txtsize=24&txt=260×200&w=260&h=200'
                });
    });

    console.log(dict);
    console.log(config);

    return dict;
}

问题是当我启动我的应用程序时,我第一次调用这个脚本时它的字典是空的,第二次它从我的数据库中有 3 行,每次我重新加载页面时,它都会增加 3 行。

我试图找出我如何处理这个问题 whiteout 有意识的希望有人可以在这里帮助我,非常感谢。

【问题讨论】:

    标签: javascript mysql node.js


    【解决方案1】:

    你应该将回调传递给 db.query,或者返回 promise 而不是 dist,因为 db.query 是一个async 方法,你不能以同步方式调用异步方法。在过去,我们会使用回调,例如

    exports.getList = function(db, conf, callback) {
       db.query('', function (err, result) {
         if(err) return callback(err);
         callback(null, result);
       });
    }
    
    getList(db,conf, function(err, result) {
      console.log(result);
    });
    

    现在我想推荐使用 promise。

    exports.getList = function(db, conf) {
        return new Promise(function(resolve, reject) {
          db.query("SELECT id, title FROM animal a " + (conf.limit > 0 ? " LIMIT " + conf.limit : "" ), function(err, rows, fields) {
              if(err) {
                  reject(err);
                  return;
              }
              var dict = [];
              for(var key in rows) {
                    var row = rows[key];
            //
                    dict.push({
                        'title' : 'Buster',
                        'animal' : 'Dog',
                        'age' : '12',
                        'photo' : 'https://placeholdit.imgix.net/~text?txtsize=24&txt=260×200&w=260&h=200'
                    });
            });
            resolve(dict);
        });
    
    }
    
    getList(db,config).then(function(result) {
      console.log(result);
    }).catch(function(e) {
      console.log(e);
    });
    

    例如,您还可以并行调用两个查询

    Promise.all([getList1(db,config), getList2(db,config)]).then(function(result) {
      console.log('result of getList1', result[0]);
      console.log('result of getList2', result[1]);
    });
    

    通过promise,你可以使用带有co的es6生成器,以同步的方式调用异步方法

    var co = require('co');
    
    co(function* () {
      try {
         var result = yield getList(db, conf);
         // here is your result
      } catch(e) {
         console.log(e);
      }
    
    });
    

    【讨论】:

    • 嗯,现在我真的是参会者了..我来自 PHP 或其他非异步语言,你能解释一下这里发生了什么以及承诺是做什么的吗?
    • 我已经得到了现在工作的承诺,我现在唯一需要修复的是,我第一次点击页面(在我的应用程序之后)是重新启动,我得到一个错误变成它从 db 什么也没说找到了,如果我重新加载所有工作,所以我第一次点击它时某些东西不起作用,我做错了什么吗?只是关注你的信息。
    • @ParisNakitaKejser 我可能会错过键入confconfig,我在getList 中看不到任何问题,您可能需要向我展示更多代码,问题可能在您的控制器中,当您将数据库传递给方法getList
    • 是的,我明白了,现在是另一个问题,每件事都运行顺利,看起来像,只有第一次解析时出现问题,我会处理的,非常感谢你打字帮助我为了完成工作,我在阅读更多内容后使用了 Promise,非常感谢。
    【解决方案2】:

    您在函数之外初始化dict 一次。此调用仅在您需要此模块时发生一次。

    稍后在函数中将新行推送给它-因此它会不断添加 ip,在调用之间没有任何东西可以清除数组。

    你应该把dict的初始化移到函数内部

    编辑:在看到您的 cmets 之后,这里还有一个(更大的)问题:您忽略了 node.js 的异步特性。

    Node 异步工作,这意味着它将依次运行db.queryconsole.logreturn 语句,而无需等待前一个结束。这意味着 return 语句可以在 db.query 之前执行并且它是回调(可能会,因为连接 db 的操作比两个控制台日志慢)。

    因此,当您不初始化 dict 时,您将获得每次在函数的上一次调用中插入的结果。一旦你清理它,你就会把它清空,因为它还没有填满。

    解决方案不应该是这样返回结果,而是将你的函数构建为一个回调,并在这个回调中返回结果(这样你可以控制这个回调何时被调用,并且只有在你有结果)

    这就是我的做法:

    exports.getList = function(db, conf, callback) {
        var dict = [];
        db.query("SELECT id, title FROM animal a " + (config.limit > 0 ? " LIMIT " + config.limit : "" ), function(err, rows, fields) {
            if(err) {
                console.log(err);
            }
    
            for(var key in rows) {
                    var row = rows[key];
            //
                    dict.push({
                        'title' : 'Buster',
                        'animal' : 'Dog',
                        'age' : '12',
                        'photo' : 'https://placeholdit.imgix.net/~text?txtsize=24&txt=260×200&w=260&h=200'
                    });
            console.log(dict);
            console.log(config);
            callback(dict); // this will return the results to the calling function's callback
        });
    
    }
    

    【讨论】:

    • 是的,我现在知道了,但是当我在函数内移动 dict 时,我无法再推送它了。
    • 为什么不呢?在任何情况下,您都可以在 for 循环之前添加 dict = [];
    • 是的,但它的工作量很大,当我这样做时它什么也没有返回,
    • @ParisNakitaKejser - 看看我对答案所做的编辑。除了我最初写的内容之外,还有更多内容
    • 我查看了您的更新,我可以看到它可能变成了它的异步是的:/ 我以前从未遇到过这个问题,所以现在我需要了解它。
    猜你喜欢
    • 2017-07-11
    • 2013-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 2020-11-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多