【发布时间】:2020-03-19 13:48:20
【问题描述】:
处理大量承诺的最有效方法是什么?我提出了 2 个解决方案,并确定 Solution 2(使用 bluebird 的 promise.map)更快。
解决方案 1(每个文件约 38 毫秒)
readFile(file) {
return new Promise((resolve, reject) => {
jsmediatags.read(file, {
onSuccess: resolve,
onError: reject
})
})
}
async readFilesHandler() {
console.time('readFilesHandler timer')
const fileArray = Array.from(this._fileSelectInput.files)
const tracksArray = []
for (let file = 0; file < fileArray.length; file++) {
await this._readFile(fileArray[file]).then(tags => {
tracksArray.push({
id: file + 1,
title: tags.tags.title || undefined,
artist: tags.tags.artist || undefined,
album: tags.tags.album || undefined,
year: tags.tags.year || undefined
})
})
}
this.dispatchEvent(new CustomEvent('tracks-selected', {
detail: tracksArray
}))
console.time('readFilesHandler timer') // ~38ms/file
}
解决方案 2(每个文件约 32 毫秒)
_readFiles() {
console.time('_readFiles timer')
const fileArray = Array.from(this._fileSelectInput.files)
window.Promise.map(fileArray, file => {
return new Promise((resolve, reject) => {
jsmediatags.read(file, {
onSuccess: resolve,
onError: reject
})
})
}, {
concurrency: 5
}).then(tags => {
const results = tags.map((tag, index) => ({
id: index + 1,
title: tag.tags.title || undefined,
artist: tag.tags.artist || undefined,
album: tag.tags.album || undefined,
year: tag.tags.year || undefined
}))
this.dispatchEvent(new CustomEvent('tracks-selected', {
detail: results
}))
})
console.timeEnd('_readFiles timer') // ~32ms/file
}
有没有更高效的实现相同结果的方法?
【问题讨论】:
-
您不受“大量承诺”的约束。您的解决方案之间的巨大区别在于,第一个顺序读取所有文件标签,而第二个一次读取 5 个,显然更快。你选择了多少个文件?
-
@Bergi 我使用 100 个 mp3 文件进行了基本测试
-
然后您可以尝试将
concurrency设置提高得更高,应该会看到一些进一步的改进(尽管不是线性的)。 -
@Bergi 如何在开始遇到内存问题之前确定我可以使用的最大
concurrency值? -
我不认为你可以 - 这取决于太多因素。
标签: javascript arrays loops promise bluebird