繁体   English   中英

如何使用Node.js异步查询大量数据?

[英]How to asynchronously query a large amount of data with Node.js?

我正在尝试从mysql数据库中查询40万行,一次获取10条。 为了异步地做到这一点,我需要使用像这样的递归:

var migrate = function(offset, size) {
  Mysql.query(query, [offset, size], function(err, rows) {
    if (!err && rows.length) {
      setTimeout(function() {
        // Pretend doing something and get next batch.
        migrate(offset + size, size);
      }, 1000);
    }
  });
};

migrate(0, 10);

问题是,第一次调用migrate()会创建其自身的子回调,并且所有这些回调都会保留在内存中,直到最后一个migrate()完成。

我想到的唯一解决方案是在while循环中同步运行它。

您能否建议如何正确执行此操作? 谢谢。

在使用mysql模块的当前示例中,可以通过查询所有记录而不进行分块并与流查询行一起使用来完成。 处理完结果后,它将一一运行查询。

Mysql.query(sql).on('result', function(row) {
  Mysql.pause();
  setTimeout(function() {
    // Pretend doing something.
    Mysql.resume();
  }, 1000);
});

但是(!), result回调不应包含任何闭包变量,因为在这种情况下,这些变量将保留在内存中。 我做了一些基准测试,这是我对它的了解,否则无法解释。

一般而言,如果您需要处理大量数据,则不管是mysql还是其他东西,我建议:

  1. 使用
  2. 使用process.nextTick()
  3. 不要使用闭包。
  4. 不要使用递归。

看一下SynJS-它允许同步运行javascript代码:

var SynJS = require('synjs');
var mysql      = require('mysql');
var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'tracker',
  password : 'tracker123',
  database : 'tracker'
});


function myMigrate(modules,connection) {
    for(var i=0; i<4; i++) {
        connection.query("SELECT CONCAT('processing data batch #',?) as res",[i], function(err, rows, fields) {
              if (err) throw err;
              console.log(i,rows[0].res);
              modules.SynJS.resume(_synjsContext);
        });
        SynJS.wait();
    }
};

var modules = {
        SynJS:  SynJS,
        mysql:  mysql,
};

SynJS.run(myMigrate,null,modules,connection,function () {
    console.log('done');
});

结果将是:

0 'processing data batch #0'
1 'processing data batch #1'
2 'processing data batch #2'
3 'processing data batch #3'
done

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM