javascript - Nodejs 中堆叠异步回调事件的最佳方式

标签 javascript node.js asynchronous node-webkit asynccallback

我正在使用 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/

相关文章:

javascript - model.find({}).populate ('place' ).populate ('location' ) 不返回地点和位置

javascript - 使用 Puppeteer 时等待文本出现

node.js - 是否可以通过 sequelize 关联表中的属性过滤查询?

javascript - 如果由 window.onbeforeunload 触发,异步 ajax 查询会完成吗?

c# - 用任务替换无限线程循环(消息泵)

javascript - 执行函数作为异步 Node.js 脚本的最后一件事

javascript - 如何遍历 div 中的 ul 元素并在提交时单独隐藏它们?

javascript - 让用户输入以 "BR"或 "BT"开头

javascript - 如何在嵌套数组中更新插入新字段

javascript - 在嵌套 for 循环内的 super 测试响应后修改对象的问题