【问题标题】:Optimal way for stacking asynchronous callback events in Nodejs在 Nodejs 中堆叠异步回调事件的最佳方式
【发布时间】:2016-05-05 19:42:16
【问题描述】:

我正在使用 Node 和 NodeWebkit 编写一个本地音乐流媒体应用程序。在我的应用程序中,我扫描音乐文件夹中的任何目录,加载专辑封面,然后以 html 显示艺术。但是,从开发人员的角度来看,在每个异步回调结束时检测 .forEach() 迭代器结束的逻辑并不能生成干净的代码。从逻辑上讲它是可行的,但如果我要解开这串依赖关系,我就必须全部重写。

这是我的代码的 sn-p:

// 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'
                                });
                            }
                        });
                    }
                });
        });
    });
});

【问题讨论】:

  • lis 在哪里初始化? if(index == array.length-1) { 应该如何工作?
  • 我推荐看看promises。
  • 您还将浏览器代码与 Node.js 代码混合在一起。
  • @djfdev NWjs @Bergi lis 在应用程序顶部进一步初始化。 lis = [];。当索引计数器到达列表中的最后一个元素时,我们知道我们已经获取了与该专辑有关的所有信息。但是我发现这并不总是正确的,因为它是异步的。

标签: javascript node.js asynchronous node-webkit asynccallback


【解决方案1】:

注 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
}

第一次。

【讨论】:

  • 这就是答案。我能够对这个解决方案进行细微的调整,我的代码和以前一样工作,现在它是结构化和可读的。
猜你喜欢
  • 2013-07-07
  • 2020-07-16
  • 1970-01-01
  • 2019-08-04
  • 2018-07-24
  • 1970-01-01
  • 2017-05-15
  • 2017-12-08
  • 1970-01-01
相关资源
最近更新 更多