2016-07-29 1 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

На полях - я рекомендую всегда отдавать предпочтения обещаниям над 'async.waterfall' (на самом деле Bluebird устраняет требуется 90% модуля 'async'). Дополнительную информацию см. В документе [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); 
     } 
*/  
     ); 
} 
Смежные вопросы