简体   繁体   中英

NodeJS executing code in wrong order. Why?

The code I've written is executing in blocks, rather than sequentially. As an example:

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

I'd like the order of execution to be like this instead:

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 

My code:

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');
    });
  }
});

The output I get is:

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

This means that the database queries are being executed only after all other work has been done. I'd like the queries to run within the loop and produce the following output instead:

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

What am I doing wrong? And how can I fix this? I'm so stuck on this problem :(

You're calling your callbacks right away before your asynchronous requests are finished. Also, you only need one async.eachSeries() (where you call the callback when your mysql query is finished).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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