【问题标题】:how can I get the final result from a array of async ?如何从 async 数组中得到最终结果?
【发布时间】:2021-10-17 17:42:26
【问题描述】:

get-video-duration 是一个获取视频时长的 npm 模块。


const { getVideoDurationInSeconds } = require('get-video-duration')

// From a local path...
getVideoDurationInSeconds('video.mov').then((duration) => {
  console.log(duration)
})

我想使用此模块从视频路径数组中获取所有视频的总时长。


function getTotals(video_Array) {
    let total_duration = 0;
    video_Array.forEach(video => {
        getVideoDurationInSeconds(video).then(duration => {
            total_duration += duration;
            
        })
    })

}

问题是getVideoDurationInSeconds 是异步的,我不能简单地返回结果。


function getTotals(video_Array) {
    let total_duration = 0;
    video_Array.forEach(video => {
        getVideoDurationInSeconds(video).then(duration => {
            total_duration += duration;
        })
    })
    return total_duration;
}

如何获得最终结果?提前谢谢!

【问题讨论】:

  • 使用map而不是forEach,创建一个包含promise的数组,然后使用promise.all。我记不太清了,但forEach 不能很好地处理承诺或异步代码

标签: javascript node.js asynchronous npm promise


【解决方案1】:

创建一个返回承诺的函数 然后用它来计算总时长

function getTotals(video_Array) {
    let video_ArrayPromises=video_Array.map(video=> 
        getVideoDurationInSeconds(video));

    return Promise.all([video_ArrayPromises]).then((values) => {
                  //Calculate TotalDuration
    return duratons.reduce((accumulator, currentValue) => accumulator + currentValue);
    });
}

getTotals(['movie1.mov','movie2.mov']).then(totalDuration => {
    //use total duration
});

【讨论】:

    【解决方案2】:

    使用map 创建一个getVideoDurationInSeconds 承诺数组,然后在Promise.all 返回的值上使用reduce 得到最终总数。

    其他文档

    // Mock function that returns a promise.
    // When it's resolved it will return a random number
    // muliplied by the element passed in through the function arguments
    function getVideoDurationInSeconds(el) {
      const rnd = Math.floor(Math.random() * (10 - 1) + 1);
      return new Promise((res, rej) => {
        setTimeout(() => {
          console.log(el * rnd);
          res(el * rnd);
        }, 1000);
      });
    }
    
    async function getTotals(videoArray) {
    
      // `map` over the elements of the video array
      // and create a new array of promises
      const promises = videoArray.map(el => getVideoDurationInSeconds(el));
    
      // Wait until all the promises have resolved
      const data = await Promise.all(promises);
    
      // Then return the sum of each total in the data array
      return data.reduce((acc, c) => acc += c, 0);
    }
    
    (async function main() {
      console.log(`Total: ${await getTotals([1, 2, 3, 4])}`);
    }());

    【讨论】:

      【解决方案3】:

      返回一个请求数组并使用reduce获取总时间。

      // Array
      function getTotalTime() {
          return videoList.map(async (video) => await getVideoDurationInSeconds(video));
      }
      
      
      // Just invoke whereever you want..
      await Promise.all(getTotalTime()).then(result => {
          let totalTime = result.reduce((acc, cv) => acc + cv, 0); // 0 = default value
      })
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多