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

Javascript 如何使用Node.js异步查询大量数据?,javascript,mysql,node.js,asynchronous,Javascript,Mysql,Node.js,Asynchronous,我试图从一个mysql数据库中查询40万行,每次查询10行。要异步执行此操作,我需要使用如下递归: var migrate = function(offset, size) { Mysql.query(query, [offset, size], function(err, rows) { if (!err && rows.length) { setTimeout(function() { // Pretend doing somethin

我试图从一个
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
循环中同步运行它

你能告诉我怎么做吗?谢谢。

在当前使用模块的示例中,可以通过查询所有记录来完成,而无需分块并使用with。一旦结果得到处理,它将逐个运行查询

Mysql.query(sql).on('result', function(row) {
  Mysql.pause();
  setTimeout(function() {
    // Pretend doing something.
    Mysql.resume();
  }, 1000);
});
但是(!),
result
callback不应该有任何闭包变量,因为在这种情况下,这些变量将保留在内存中。我做了一些基准测试,这是我如何知道它的,不能解释它

一般来说,如果您需要处理大量数据,不管是mysql还是其他什么,我建议您:

  • 使用
  • 使用
  • 不要使用闭包
  • 不要使用递归
  • 看一看-它允许同步运行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');
    });
    

    找到一种减少所需调用量的方法,可以编写更复杂的sql(这样就不需要40万行),也可以同时请求更多的行。或者只获取要立即使用的行。如果前端同时需要400k行,那么可能存在设计问题。您还可以重写该函数,使其不是递归的,而是交给另一个函数来处理返回的数据并再次调用migrate。如果您克隆或取消引用返回的数据,prev ajax调用应该能够被垃圾收集并释放内存。好建议。从技术上讲,如果正确使用流,可以使用闭包和递归。它们只有在保留大量内存时才会出现问题,如果使用流,这是不可能发生的
    0 'processing data batch #0'
    1 'processing data batch #1'
    2 'processing data batch #2'
    3 'processing data batch #3'
    done