NodeJS使请求同步

时间:2019-01-13 13:35:03

标签: node.js

我正在接收视频文件列表。对于收到的每个文件,我都使用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/'
                    });
        });
});

2 个答案:

答案 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);
});