我正在使用 Node 和 NodeWebkit 编写本地音乐流应用程序。在我的应用程序中,我扫描音乐文件夹中的所有目录,加载专辑封面,然后以 html 形式显示该封面。但是,从开发人员的 Angular 来看,在每个异步回调结束时检测 .forEach()
迭代器结束的逻辑并不能生成干净的代码。从逻辑上讲它是有效的,但如果我要解开这串依赖关系,我就必须重写所有它。
这是我的代码片段:
// Fetch the music albums
fs.readdir("./music", function(err, files) {
if (err) {
//return console.error(err);
}
//document.write(JSON.stringify(files));
// Look specifically for music album folders (directories)
filterDirectories("./music", files, function(dirs){
dirs.forEach(function(dir, index, array){
fs.readFile('./music/' + dir + "/album.json", 'utf-8', function (err, data) {
data = JSON.parse(data);
if (err) {
return console.error(err);
}
// Create a li item for every album, and append it to the unordered list
var li = $('<li><img /><a target="_blank"></a></li>');
li.find('a')
.attr('href', '#')
.text(data.album_name);
li.find('img').attr('src', './music/' + dir + '/' + data.album_art_loc).css('width:512px;height:512px;');
lis.push(li);
// Is this the last album folder?
if(index == array.length-1) {
// Go through the array
lis.forEach(function(item, index, array){
// add to the ul element
item.appendTo(ul);
// Have we added the last one to the ul element?
if(index == array.length - 1){
// Ok, now we initialize the flipster plugin to make it look 3D and advanced
$('.flipster').flipster({
style: 'carousel'
});
}
});
}
});
});
});
});
最佳答案
注意1,Array.forEach是同步的。因此,要初始化 Flipster,您不需要检查 last 循环的结尾。您可以将其放在循环后面。
注意2,要读取每个album.json文件,你有正确的方法。尽管如此,您可能想使用像 async 这样的助手。 。它通常是为了处理这种情况而存在的。
请检查代码,我使用异步重写了它。我不保证它没有错误,但最终的代码应该非常相似。
注 3,初始 fs.readdir 和对 filterDirectories 的调用似乎可以合并到一个异步函数中。
注释4,可能值得阅读this
代码重写
var async = require('async')
var musicFiles;
var musicDirs;
var lis = [];
async.series([
function (next) {
fs.readdir("./music", function(err, files) {
if (err) next(err);
musicFiles = files;
next();
});
},
function (next) {
filterDirectories("./music", files, function(dirs){
musicDirs = dirs;
next();
});
},
function (next) {
var todos = [];
musicDirs.forEach(function(dir){
todos.push(function (nextTodo) {
fs.readFile('./music/' + dir + "/album.json", 'utf-8', function (err, data) {
if (err) nextTodo(err);
lis.push(createLi(JSON.parse(data)));
nextTodo();
});
})
});
async.parallelLimit(todos, 4, next);
},
function (next) {
lis.forEach(function(li){
li.appendTo(ul);
});
$('.flipster').flipster({
style: 'carousel'
});
}
], function () {
console.log("All done !")
})
function createLi (data) {
var li = $('<li><img /><a target="_blank"></a></li>');
li.find('a')
.attr('href', '#')
.text(data.album_name);
li.find('img').attr('src', './music/' + dir + '/' + data.album_art_loc).css('width:512px;height:512px;');
return li
}
第h。
关于javascript - Nodejs 中堆叠异步回调事件的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37058985/