希望你们好吗? 我正在深入研究Node.js并且不得不重新学习我以前用于编码的许多方法 - 并且必须重新训练自己以异步方式...我正在编写服务器端脚本(如java POJO),将从命令行运行或从事件触发。
我希望将一个函数的输出(返回)作为下一个的输入,所以我决定使用async.waterfall - 因为我读到这将按顺序执行函数,使用一个函数的输出作为输入另一个......
脚本的想法是遍历给定的文件夹结构,创建一个子文件夹数组,然后将该数组传递给下一个。然后对该数组中的每个路径执行相同操作。我想使用underscore.js和“_.each()”函数,因为它似乎是按顺序迭代数组的好方法。但是这就是我被困住的地方,因为它似乎在工作完成之前通过所有功能落到最后。所以我的逻辑有点偏离......
我使用'walk'函数进入文件夹并返回所有子文件夹..想法是脚本将运行,然后在瀑布的末尾运行'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'函数,但是完全跳过'walk',即使'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 :(得分:0)
您的walk
函数似乎是异步的。并且您希望触发并行异步作业,结合结果并向下移动瀑布。因此,您可以将async.waterfall
与async.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
功能。