我正在接收视频文件列表。对于收到的每个文件,我都使用Fluent-ffmpeg提取缩略图。我面临的问题是缩略图提取是异步的,提取完成后我必须发送响应。目前,甚至在提取第一个缩略图之前就发送了响应。我知道我应该使用 async / await 方法,但是由于提取缩略图的功能是node_modules包的一部分,因此尚不清楚。
router.post('/files', function (req, res) {
let fileList = req.body;
fileList.forEach(function (file) {
ffmpeg(file)
.on('end', function() {
console.log('Screenshots taken');
})
.screenshots({
count: 1,
filename: tempFileName + '.png',
folder: '/someFolder/'
});
});
res.send(true);
});
我可能想到的可能的解决方法是获取fileList数组的长度,然后在ffmpeg结束回调中创建一个计数器。如果fileList的长度等于计数器,则可以发送响应。我不喜欢这种方法,我相信有更好的方法。
它看起来像:
router.post('/files', function (req, res) {
let fileList = req.body;
let counter = 0;
fileList.forEach(function (file) {
ffmpeg(file)
.on('end', function() {
console.log('Screenshots taken');
counter++;
if(counter === fileList.length){
res.send(true);
}
})
.screenshots({
count: 1,
filename: tempFileName + '.png',
folder: '/someFolder/'
});
});
});
答案 0 :(得分:0)
通过处理每个文件并仅在处理完每个文件后发送响应,来利用async模块的强度。
var async = require('async');
router.post('/files', function (req, res) {
let fileList = req.body;
async.each(fileList, function(file, callback){
ffmpeg(file)
.on('end', function() {
console.log('Screenshots taken');
callback();
})
.screenshots({
count: 1,
filename: tempFileName + '.png',
folder: '/someFolder/'
});
}, function(){
res.send(true);
});
});
async.each()
将有效地开始每个文件的处理,而不必等待上一个文件的完成。如果要等待文件处理完成以开始新文件,只需将async.each()
替换为async.eachSeries()
。
答案 1 :(得分:0)
如果您知道异步/等待,请使用它(推荐)。
router.post('/files', async function(req, res) {
let fileList = req.body;
// process in step by step
for (let i = 0; i < fileList.length; i++) {
let file = fileList[i];
await new Promise((resolve, reject) => {
ffmpeg(file)
.on('end', function () {
console.log('Screenshots taken');
resolve();
})
.screenshots({
count: 1,
filename: tempFileName + '.png', // what is your `tempFileName` ???
folder: '/someFolder/'
});
});
}
// all done!
res.send(true);
// process in parallel
// let promises = fileList.map((file) => {
// return new Promise((resolve, reject) => {
// ffmpeg(file)
// .on('end', function () {
// console.log('Screenshots taken');
// resolve();
// })
// .screenshots({
// count: 1,
// filename: tempFileName + '.png',
// folder: '/someFolder/'
// });
// });
// });
// await Promise.all(promises);
// // all done!
// res.send(true);
});