【问题标题】:Node.JS asynch call backNode.JS 异步回调
【发布时间】:2017-03-20 02:10:25
【问题描述】:

我只是在学习 node.js,所以对于我的第一个应用程序,像很多人一样,我正在创建一个音乐库,这样我就可以在家里的服务器上通过网络浏览器收听我的音乐。

我做得很好...但我很难理解如何不制造意大利面条的噩梦。我正在使用 Promise 并使用异步库来帮助解决这个问题。但是我有这个当前场景,我试图了解如何知道它何时完成,以便它可以执行必要的回调函数。

基本上,要点是我使用了一个异步库来执行两次调用,一次调用数据库,一次调用文件夹,这样我就可以将数据库中的文件与硬盘驱动器上指示的文件进行比较。每个异步方法完成后,它会返回到我正在使用的异步库提供的“完成”回调。

此时我想通过比较两个列表并插入一个音乐文件,这些文件从数据库中丢失但在硬盘驱动器上找到。然后我想将整个列表发送回客户端,以便在网格中显示。

我正在使用 metamusicdata 库来执行此操作。到目前为止,这是我的代码(未经测试/未完全完成)

function(err, results) {
    console.log("ASYNC COMPLETED");
    if (err) $this.callback(err, null);
    var db = linq.asEnumerable(results.dbList);
    var files = linq.asEnumerable(results.foldersList);
    var filesToInsert = db.Where(d => !files.Contains(d.LocFile));
    var newMusicList = [];
    for (var file in filesToInsert) {
        if (file.indexOf('mp3') || file.indexOf('mp4')) {
            var fileData = musicMetaData(fs.createReadStream(file), function (err, metadata) {
                if (err) throw err;
                newMusicList.push(new Music ({
                    locFile : file,
                    artist : fileData.artist,
                    album : fileData.album,
                    albumArtist : fileData.albumartist,
                    title : fileData.title,
                    track : fileData.track.no,
                    totalTracks : fileData.track.of,
                    genre : fileData.genre,
                    image : fileData.picture.data,
                    imageType : fileData.picture.format,
                    duration : fileData.duration,
                    createdDate : Date.now(),
                    classification : "unknown"
                }));
                console.log(metadata);
            });
        }
    }
    //insert into database here the array I created.
    var insertMyFiles.
    //query database for the entire list
    var musicListDb;
    //return to the callback so it can send the results back to the client browser.
    return $this.callback(err, musicListDb);
}

问题是我如何设置它以了解文件循环何时完全完成?所以我可以创建我的数组并将新条目插入到数据库中?那么我可以调用另一个查询并获取可用音乐的更新列表吗?

我能想到我认为非常糟糕的做法。这将用 for i=to 长度替换 for in。然后在最后的音乐元数据回调中检查是否 i+1=length 如果是,则在其中调用回调。

这对我来说似乎不对,而且在我眼里是相当的胡言乱语。

我在这里没有看到或理解什么解决方案?

【问题讨论】:

  • 那么为什么有人对我的问题投了反对票而没有评论如何改进它?想知道为什么?

标签: javascript node.js asynchronous


【解决方案1】:

考虑使用async,使用它真的很容易摆脱所谓的“回调地狱”等等。

【讨论】:

  • 我已经在使用我所说的异步了。我正在研究的领域是异步调用的已完成功能。在那种情况下,我看不到任何使用异步库的方法,这对我来说对 metadatamusic 库调用有任何用处。
  • 你的函数太复杂了,你仍然可以把它分成多个独立的逻辑部分。检查this disqussion about async.waterfall
  • 感谢您提供有助于更好理解的附加链接...我所做的是使用 async.eachLimit 而不是 for 循环。我发现如果我出于某种原因使用了 async.Each,它会创建阻塞的 io 并显着减慢响应速度,并最终导致堆栈溢出。基本上我发现我一次只能处理 5 个。
【解决方案2】:

为此,我使用 Promise 和/或 async/await。

异步/等待是最简单的。您只有一个普通的 for 循环,但等待您的数据。

如果您需要它并行运行,您可以使用 promise-all-clear 模块或仅使用带有 catch() 的 Promise.all 之类的东西

async function load() {
  const calls = files.map(async f => {
     try { return await meta(f) }
     catch() { return null } 
   });
  let metas = await Promise.all(calls);
  metas = metas.filter(m=>m != null);
  await insert(metas);
}      

【讨论】:

    猜你喜欢
    • 2013-12-15
    • 2012-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-15
    • 2012-07-15
    • 2018-04-29
    相关资源
    最近更新 更多