2014-05-15 19 views
0

希望你們好? 我深入瞭解Node.js,並且需要重新學習很多我用來編寫代碼的方法 - 並且不得不重新訓練自己以異步方式......我正在編寫一個服務器端腳本(如java POJO),它可以從命令行運行,也可以從事件觸發。async.waterfall在函數完成之前跳到結尾

我想將一個函數的輸出(返回)作爲下一個的輸入,所以我決定使用async.waterfall - 因爲我讀到這個函數將按順序執行函數,使用一個函數的輸出其他輸入...

腳本的思想是遍歷給定的文件夾結構,創建一個子文件夾數組,然後將該數組傳遞給下一個。然後對該陣列中的每個路徑執行相同操作。我想使用underscore.js和「_.each()」函數,因爲它似乎是按順序遍歷數組的好方法。但是這是我陷入困境的地方,因爲在工作完成之前,它似乎貫穿所有功能到最後。所以我的邏輯是有點偏離某處..

我使用'走'功能進入文件夾並返回所有子文件夾..這個想法是,腳本將運行,然後'process.exit() '在瀑布的盡頭。

的代碼是:



    async.waterfall([ 
     function(callback){ /* Get List of Artists from MusicFolder */ 
     console.log('first->IN'); 
     walk(musicFolder, function(err, foldersFound) { 
      if (err) { return err;} 
      _.each(foldersFound, function(folderPath){ 
      console.log('Folder: ' + folderPath); 
      }); 
      console.log('first->OUT'); 
      callback(null, foldersFound); 
     }); 
     }, 
     function(artistsFound, callback){ /* Get List of Albums from Artist Folders */ 
     var eachLoop=null; 
     console.log('second->IN'); 
     _.each(artistsFound, function(artistPath){ 
      console.log('second->eachPath:Start:'+artistPath); 
      walk(artistPath, function(err, albumsFound) { 
      console.log('second->Walk:Found'); 
      console.log(albumsFound); 
      if (err) { console.log(err);} 
      _.each(albumsFound, function(albumPath){ 
       eachLoop++; 
       console.log('second->Walk:each:'+eachLoop); 
      }); 
      console.log('second->Walk:End'); 
      }); 
      console.log('second->eachPath:End:'+artistPath); 
     }); 
     console.log('second->OUT'); 
     callback(null, albumsFound); 
     }, 
     function(paths, callback){ 
     console.log('third->IN'); 
     console.log('third->OUT'); 
     callback(null, paths); 
     } 
    ], function (err, result) { 
     console.log('last->IN'); 
     console.log(result); 
     console.log('last->OUT'); 
    // process.exit(); 
    }); 

我已經在示例註釋掉 'process.exit()'。

如果我取消了「process.exit()」我得到以下輸出:

first->IN 
Folder: /music/Adele 
Folder: /music/Alex Clare 
first->OUT 
second->IN 
second->eachPath:Start:/music/Adele 
second->eachPath:End:/music/Adele 
second->eachPath:Start:/music/Alex Clare 
second->eachPath:End:/music/Alex Clare 
second->OUT 
third->IN 
third->OUT 
last->IN 
null 
last->OUT 

我可以看到的是它並沒有在第二瀑布功能進入「走」的功能,但跳過即使'walk'在_.each()迭代中,也完全「走」。

如果我註釋掉了「process.exit()」中的最後一個函數命令我得到如下結果:

first->IN 
Folder: /music/Adele 
Folder: /music/Alex Clare 
first->OUT 
second->IN 
second->eachPath:Start:/music/Adele 
second->eachPath:End:/music/Adele 
second->eachPath:Start:/music/Alex Clare 
second->eachPath:End:/music/Alex Clare 
second->OUT 
third->IN 
third->OUT 
last->IN 
null 
last->OUT 
second->Walk:Found 
[ '/music/Alex Clare/The Lateness of the Hour' ] 
second->Walk:each:1 
second->Walk:End 
second->Walk:Found 
[ '/music/Adele/19', 
    '/music/Adele/21', 
    '/music/Adele/Live At The Royal Albert Hall' ] 
second->Walk:each:2 
second->Walk:each:3 
second->Walk:each:4 
second->Walk:End 

我得承認,這是令人沮喪的。任何幫助都將不勝感激,因爲我在過去一週內以各種「異步」形式反覆重寫了這些內容,並且它們都過早地跳出了功能 - 因此一切都失靈了。

感謝您的幫助或想法提前:)

馬克

回答

0

看來你walk功能是異步的。並且您想要啓動並行異步作業,合併結果並向下移動瀑布。所以你可以做的是結合async.waterfallasync.parallel。你的第二個功能可能是這樣的:

function(artistsFound, callback) { 
    // some code 
    var jobs = []; 
    artistsFound.forEach(function(artistPath) { 
     jobs.push(function(clb) { 
      walk(artistPath, function(err, albumsFound) { 
       // some code 
       clb(err, albumsFound); 
      }); 
     }); 
    }); 
    // some code 
    async.parallel(jobs, callback); 
} 

旁註:你不必在一個陣列中使用的underscore.js簡單地循環。現代JavaScript具有內置的.forEach功能。

+0

'走'功能不是異步的 - 只有在走完所有文件夾並將它們添加到完成傳遞的數組後纔會返回。 - 我想粘貼在這裏,但不允許,因爲我不能回答'答案'。所以不知道你的async.parallel選項是否會起作用 - 實際上已經嘗試過了,它和我的公平性一樣... :)欣賞那裏有一個javascript。forEach,但我也在教自己underscorejs,所以認爲應該習慣使用它。 – Pandafinity

+0

@Pandafinity如果'walk'函數是同步的,那麼我不相信代碼會執行你所說的操作。 :)無論如何,我沒有想法,所以我希望別人能解決你的問題。祝你好運! – freakish

+0

謝謝你的想法和建議:) ...這是一個標準的'走',只是返回字符串數組一次完成..所以你只是'[子文件夾路徑1','子文件夾路徑2',... ]返回數組類型。希望你的陽光明媚。 – Pandafinity

相關問題