2014-06-22 47 views
0

我寫的代碼以塊爲單位執行,而不是按順序執行。 作爲一個例子:NodeJS以錯誤的順序執行代碼。爲什麼?

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 ----: ..... 

Th意味着數據庫查詢只有在所有其他工作完成後才能執行。我希望查詢在循環內運行並生成以下輸出:

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

您是否瞭解異步執行以及您的函數中執行順序的含義? – jfriend00

+0

類型。我只知道同步代碼是阻塞的,異步代碼不是。意思是程序將繼續執行代碼if它是在一個異步塊之後,對嗎? –

+0

是的,一個異步操作被啓動,然後你的代碼的其餘部分繼續運行,異步操作在稍後的某個時間完成並且當時你的回調被稱爲表示具體的操作已經完成並且結果可用。多個異步操作沒有自然保證的完成順序。如果你想以特定的順序運行異步操作,你必須編寫特殊的代碼來做到這一點。你正在使用的'async'庫將幫助你做到這一點(它具有這樣做的功能)。 – jfriend00

回答

0

你在異步請求完成之前立即調用你的回調函數,並且你只需要一個async.eachSeries()(當你的mysql查詢完成時你調用callback)。