我的头衔很糟糕。让我详细说明一下:
我正在使用节点7.2.0和Electron。我有一组Song
个对象,其中一个键叫filepath
。我需要为每首歌按顺序执行以下操作:
所以我需要知道的是:链接异步函数的最佳方法是什么,以及如何在链完成时实现回调。
我应该尽快通过所有步骤运行每个song
吗?我应该等到所有歌曲都完成第1步,然后转到第2步,然后在第3步完成所有第2步,等等。
其次,当所有上述步骤(可能在forEach
循环中)完成时,运行回调的可接受方式是什么?我应该使用节点async
库还是承诺?我一直在读,我应该在承诺中包含每个单一函数,然后使用Promise.all()
来运行回调,但我不确定它是否是最新的。
编辑:代码示例。它并不多,但它只是我拥有的一切。在我潜入太远之前,我决定问这个问题,后悔我的选择。
let songs = SongHelpers.createSongArray(MUSIC_DIR);
songs.forEach((song) => {
// I'm putting the contents of the applyMetadata function here to ease readability for this question
// SongHelpers.applyMetadata(song, callback);
// mm is from the musicmetadata package: https://github.com/leetreveil/musicmetadata
mm(fs.createReadStream(song.filepath), function (err, metadata) {
try {
if (err) throw (err);
return metadata;
} catch (e) {
console.error(`Error in mm parsing: ${e.message}`);
}
});
// Then send to API
// Then apply API response to each track
// etc.
});
答案 0 :(得分:1)
概述您可以使用Promises做什么
let songs = SongHelpers.createSongArray(MUSIC_DIR);
Promise.all(songs.map(song => new Promise((resolve, reject) => {
mm(fs.createReadStream(song.filepath), function (err, metadata) {
if (err) {
return reject(err);
}
resolve(metadata);
})).then(metadata => {
// Send artist and track info to API,
// should return a Promise that resolves when the API returns a result
}).then(result => {
// apply correct track information, return some value that could be used in the sort step
});
})).then(results => {
// results is an array of values returned in the last step above
// sort and display here
}).catch(err => {
// handle error here
});