我正在学习node.js所以对于我的第一个应用程序,就像很多人一样,我正在创建一个音乐库,所以我可以通过网络浏览器从家里的服务器上听我的音乐。
我做得很好......但是我很难理解如何不制造一个意大利面的噩梦。我正在使用promises并使用异步库来帮助解决这个问题。但我有这个当前的情况我试图了解如何知道它何时完成,以便它可以预先形成必要的回调函数。
基本上,我已经使用异步库对数据库执行两次调用,对文件夹执行一次调用,这样我就可以将数据库中的文件与硬盘驱动器上指示的文件进行比较。完成每个异步方法后,它将返回到我正在使用的异步库提供的“完整”回调。
此时我想通过比较两个列表并插入数据库中缺少但在硬盘驱动器上找到的音乐文件。然后我想将整个列表发送回客户端以便在网格中显示。
我正在使用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 =替换for for。然后在最后的音乐元数据回调中检查i + 1 =长度是否如此,然后在那里调用回调。
这对我来说似乎不对,而且在我眼中是相当狡猾的。
我在这里没有看到或理解的解决方案是什么?
答案 0 :(得分:1)
考虑使用async,它很容易摆脱所谓的"回调地狱"还有更多。
答案 1 :(得分:1)
为此,我使用promises和/或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);
}