for循环中的异步函数

时间:2017-08-29 17:28:55

标签: javascript node.js

您好我正在尝试将sqlite数据库转换为NeDb,使用此代码:

const sqliteJSON = require('sqlite-json');
const Datastore = require('nedb')

const exporter = sqliteJSON('etecsa.db');

db = new Datastore('etecsa.nedb');
db.loadDatabase();

tables = ['fix','movil'];

tables.forEach(function(table) {
    sql = 'select count(1) from ' + table;

    exporter.json(sql, function (err, json) {
        toNeDB(table, JSON.parse(json)[0]['count(1)'])
    });

}, this);

var toNeDB = function(table, count) { 
    var inc = 10000;
    console.log(table + ' => ' + count)

    for (var i = 0; i < count + inc; i += inc) {
        var sql = 'SELECT * FROM ' + table + ' ORDER BY province ASC, number DESC LIMIT '+ i + ' , ' + inc;
        console.log(i)
        exporter.json(sql, function(err, json) {
            var data = JSON.parse(json);
            db.insert(data, function (err, newDoc) {});
        });
    }
}

问题是for循环不能按我的意愿工作。我需要使用它来更改sql分页,因为sqlite数据库非常庞大,我无法在单个查询中传递所有数据。

使用async.map更新

const sqliteJSON = require('sqlite-json');
const Datastore = require('nedb')
var range = require("range");
var async = require("async");

const exporter = sqliteJSON('etecsa.db');

db = new Datastore('etecsa.nedb');
db.loadDatabase();

tables = ['fix','movil'];

tables.forEach(function(table) {
    sql = 'select count(1) from ' + table;

    exporter.json(sql, function (err, json) {
        toNeDB(table, JSON.parse(json)[0]['count(1)'])
    });

}, this);


var toNeDB = function(table, count, cb) { 
    var inc = 10000;
    var pagination = range.range(1,count+inc,inc)

    async.map(pagination, function (page, cb){
        var sql = 'SELECT * FROM ' + table + ' ORDER BY province ASC, number DESC LIMIT '+ page + ' , ' + inc;
        console.log(page, table, inc);
        exporter.json(sql, function(err, json) {
            var data = JSON.parse(json);
            console.log(data[0])
            db.insert(data, function (err, newDoc) {});
        });
    }.bind({ table: table, inc: inc }), function(err,results){

    })

}

和输出:

1 'fix' 10000
10001 'fix' 10000
....
1150001 'fix' 10000

1 'movil' 10000
10001 'movil' 10000
...
3730001 'movil' 10000


{ number: '8775031',
  name: 'UNION ELECTRICA',
  address: 'S ALLENDE #666 OQUENDO SOLEDAD',
  province: 7 }
{ number: '8734454',
  name: 'EMP ESTB ESP Y SERVICIOS',
  address: 'ESAPDA #256 CONCORDIA S LAZARO',
  province: 7 } 

2 个答案:

答案 0 :(得分:1)

如果您需要知道每个操作何时发生,您应该将console.log放在回调中。

类似的东西:

var toNeDB = function(table, count) { 
var inc = 10000;
    console.log(table + ' => ' + count)

    for (var i = 0; i < count + inc; i += inc) {
        var sql = 'SELECT * FROM ' + table + ' ORDER BY province ASC, number DESC LIMIT '+ i + ' , ' + inc;

        exporter.json(sql, (function(i) {
           return function(err, json) {
              console.log(i)
              var data = JSON.parse(json);
              db.insert(data, function (err, newDoc) {});
           }
        })(i));
    }
}

答案 1 :(得分:1)

您可以使用递归而不是循环,这样您就可以确保下一次迭代不会执行直到第一次迭代完成。

var proc = function (i, count, table) {
  var sql = 'SELECT * FROM ' + table + ' ORDER BY province ASC, number DESC 
             LIMIT ' + i + ' , ' + inc'
  console.log(i)
  exporter.json(sql, function (err, json) {
    var data = JSON.parse(json)
    db.insert(data, function (err, newDoc) {
      if (i < count) {
        i += inc
        proc(i, count, table)
      }
    })
  })
}
var toNeDB = function (table, count) {
  var inc = 10000
  console.log(table + ' => ' + count)
  proc(0, count, table)
}

让我知道是否有效