2016-07-29 49 views
0

我正在爲循環中的每個配置文件運行瀑布。在瀑布的第一個功能中,我從SFTP下載文件。從我讀到的關於瀑布的內容來看,它應該等到一個函數完成後纔開始下一個函數。NodeJs中的瀑布似乎是異步的。爲什麼?

發生在我身上的事情恰恰相反。

呼籲在一個循環的每個配置文件中的瀑布功能:

for (var i=0; i<configFiles.length; i++) { 
    waterfallMain(configFiles[i],i); 
} 

瀑布功能:

function waterfallMain(configFile, i) { 
    async.waterfall([ 
    function(callback) { 
     // If there is no such file error is thrown and next iteration of the loop starts 
     util.log("Downloading config files."+i); 
     sftpHandler.downloadFile(credentials.sftpPathToImportFiles+configFile.importFileName, callback); 
       }, 
    function(callback) { 
     // Change file encoding to UTF8 
     util.log("Going to change file name of the file on SFTP prepending in_progress."); 
     sftpHandler.renameFileOnSftp(); 
    }, 
    function(callback) { 
     // Change file encoding to UTF8 
     util.log("Going to change file encoding to UTF8."); 
     readFileSync_encoding(configFile.importFileName, "ISO-8859-1", callback); 
    }, 
    function(fileData, callback) { 
     util.log("Parsing the file data."); 
     parseFileData(fileData, configFile, callback); 
    }], 
    // the bonus final callback function 
    function(err, status) { 
     if (err) { 
     // app has crashed 
     util.log(err); 
     return; 
     } 
     // keep looping with 1 min delay 
     util.log(status); 
     setTimeout(function() { 
     mainProcess(); 
     }, 60000); 
     return; 
    }); 
} 

而且downloadFile功能:

SftpHandler.prototype.downloadFile = function (path, callback) { 
    // Download swush file from SFTP 
    client.scp({ 
     'host': this.host, 
     'username': this.username, 
     'password': this.password, 
     'path': path 
     },'./', function(err) { 
     if (err) { 
      return callback("File: "+path+" "+err); 
     } else { 
      return callback(null); 
     } 
     }); 
}; 

和輸出:

29 Jul 11:58:01 - Main process started. 
29 Jul 11:58:01 - Running through all config files. Count: 3 
29 Jul 11:58:01 - Downloading config files.0 
29 Jul 11:58:01 - Downloading config files.1 
29 Jul 11:58:01 - Downloading config files.2 
29 Jul 11:58:02 - File: /E-drive/sftp/VismaReports/Test/QueueSystem/test2.csv Er 
ror: file does not exist 
29 Jul 11:58:03 - File: /E-drive/sftp/VismaReports/Test/QueueSystem/test5.csv Er 
ror: file does not exist 
29 Jul 11:58:03 - Going to change file name of the file on SFTP prepending in_pr 
ogress. 

我不希望看到Downloading config files.+i在實際下載發生之前看到那裏3次。在我看來,這是異步的,我不希望它是異步的。

+1

您對async.js的作用有誤解。它不可能將異步功能轉換爲同步功能。它不可能等待。你可以做的是管理什麼時候被調用的函數的流程。這就是爲什麼您將函數數組傳遞給瀑布以允許它們按順序執行它們的原因。但是,如果你調用第二個瀑布,那麼這兩個瀑布進程將並行執行(在它們每一個的順序中都是如預期的那樣) – slebetman

+0

在邊距上 - 我推薦始終比Promise優先於'async.waterfall'(事實上,Bluebird消除需要90%的「異步」模塊)。有關更多詳細信息,請參見[Bluebird promisification](http://bluebirdjs.com/docs/api/promisification.html)。 – Ginden

回答

0
for (var i=0; i<configFiles.length;i++){ 
     waterfallMain(configFiles[i],i); 
} 

您將異步代碼作爲同步運行。像下面這樣嘗試

async.eachSeries(configFiles, waterfallMain, function(err) { // sequence run 
    console.log((err) ? err.message : 'Done')}; 

    // Process error here 
}) 
... 
function waterfallMain(configFile, callback){ 
    async.waterfall([ 
      function(callback){ 
       util.log("Downloading config files.", configFiles); 
       sftpHandler.downloadFile(credentials.sftpPathToImportFiles+configFile.importFileName, callback); 
      }, 
      function(callback) { 
       util.log("Going to change file name of the file on SFTP prepending in_progress."); 
       sftpHandler.renameFileOnSftp(callback); // !!! You must call callback function to move next 
      }, 
      function(callback) { 
       util.log("Going to change file encoding to UTF8."); 
       readFileSync_encoding(configFile.importFileName, "ISO-8859-1", callback); // !!! Smth wrong readFileSync_encoding like sync-function. Why it call callback? 
      }, 
      function(fileData, callback) { 
       util.log("Parsing the file data."); 
       parseFileData(fileData, configFile, callback); 
      }], 
      callback // !!! simple call callback. Errors processing above. 
/* This function is not good 
     // the bonus final callback function 
     function(err, status) { // !!! what is status? Where it's set? 
      // app has crashed 
      if (err) 
       return util.log(err); // !!! shortly 

      // !!! WTF?! 
      // keep looping with 1 min delay 
      util.log(status); 
      setTimeout(function(){ 
       mainProcess(); 
      }, 60000); 
     } 
*/  
     ); 
}