NodeJS以错误的顺序执行代码。为什么?

时间:2014-06-22 16:23:55

标签: node.js asynchronous node-mysql

我写的代码是以块的形式执行,而不是按顺序执行。 举个例子:

Task 1 result Task 1 result Task 1 result

Task 2 result Task 2 result Task 2 result

Task 3 result Task 3 result Task 3 result

我希望执行的顺序是这样的:

Task 1 result Task 2 result Task 3 result

Task 1 result Task 2 result Task 3 result

Task 1 result Task 2 result Task 3 result 

我的代码:

var async = require('async');
var fs = require('fs');
var mysql = require('mysql');

var connection = mysql.createConnection({
  host     : 'localhost',
  user     : 'root',
  password : '',
});

function getFiles(dir,files_){
    files_ = files_ || [];
    if (typeof files_ === 'undefined') files_=[];
    var files = fs.readdirSync(dir);
    for(var i in files){
        if (!files.hasOwnProperty(i)) continue;
        var _name = files[i];
        var name = dir+'/'+files[i];
        if (fs.statSync(name).isDirectory()){
            getFiles(name,files_);
        } else {
            files_.push(_name);
        }
    }
    return files_;
}

connection.connect(function(err) {

  if(err){
    console.log('error: '+err);
  }else{
    var directory = "products_json/13658/";
    var all_files = getFiles(directory);

    async.eachSeries(all_files, function( file, callback) {

      // Skip an iteration if the file is a mac .DS_STORE file
      if(file !== ".DS_Store"){

        console.log('Processing file ' + directory + file);

        fs.readFile(directory+file, function read(err, fileData){
          var productsData = JSON.parse(fileData); 
          async.eachSeries(productsData.results, function( product, callback2) {

            async.eachSeries(Object.keys(product), function( productKey, callback3) {

              var checkIfColumnExistsQuery = connection.query(
                "SELECT * FROM information_schema.COLUMNS WHERE TABLE_SCHEMA =  ? AND TABLE_NAME =  ? AND COLUMN_NAME =  ? LIMIT 0 , 30;",
                ['unisaver', 'products', productKey],
                function(err, rows, fields) {
                  // Create the field if it doesn't exist
                  if(rows.length == 0){
                    console.log(productKey + " --- "+ typeof product[productKey] + " --- "+ product[productKey]);

                    if( typeof product[productKey] === 'object' ){
                      var createColumnQuery = connection.query(
                        "ALTER TABLE ?? ADD ?? TEXT(1000);", 
                        ['unisaver.products', productKey]
                      );
                    }else if( typeof product[productKey] === 'string' ){
                      var createColumnQuery = connection.query(
                        "ALTER TABLE ?? ADD ?? VARCHAR(255);", 
                        ['unisaver.products', productKey]
                      );
                    }else if( typeof product[productKey] === 'number' ){
                      var createColumnQuery = connection.query(
                        "ALTER TABLE ?? ADD ?? INT(11);", 
                        ['unisaver.products', productKey]
                      );
                    }
                  }
                }
              );
              callback3();
            });

            // TODO: Insert a row
            callback2();

          });
        });
      }
      callback();
    }, function(err){
       console.log('finished');
    });
  }
});

我得到的输出是:

Processing file products_json/13658/0.json
Processing file products_json/13658/1.json
Processing file products_json/13658/10.json
price ----: .....
price ----: .....
price ----: .....

这意味着只有在完成所有其他工作后才会执行数据库查询。我希望查询在循环中运行并生成以下输出:

Processing file products_json/13658/0.json
price ----: .....
Processing file products_json/13658/1.json
price ----: .....
Processing file products_json/13658/10.json
price ----: .....

我做错了什么?我该如何解决这个问题?我是如此坚持这个问题:(

1 个答案:

答案 0 :(得分:0)

您在异步请求完成之前立即调用回调。此外,您只需要一个async.eachSeries()(在您的mysql查询完成时调用callback)。