【问题标题】:Downloading images from the list of links in the same order以相同顺序从链接列表中下载图像
【发布时间】:2021-04-28 03:51:30
【问题描述】:

我需要像https://miro.medium.com/max/1200/0*UEtwA2ask7vQYW06.png这样从指向它们的链接数组中下载图像

还有我写的代码。我用https://www.npmjs.com/package/image-downloader

const download = require('image-downloader');
const links = require('./links.json');

var options = {
  url: "",
  dest: links.dest,
};

  links.url.forEach((link) => {
    options.url = link
   download
    .image(options)
    .then((result) => {
      console.log("Image downloaded", result);
    })
    .catch((error) => console.log("downloaded error", error));
  });

还有 .json 文件

{
"url":[
"https://miro.medium.com/max/1200/0*UEtwA2ask7vQYW06.png",
"https://api.time.com/wp-content/uploads/2019/08/better-smartphone-photos.jpg",
"https://iso.500px.com/wp-content/uploads/2016/03/stock-photo-142984111.jpg",
]
"dest":"D:/"
}

但是因为它是异步工​​作的,所以所有下载的图像都是无序的,不像链接列表中那样(不能按日期排序)。如何修改此代码以使其按顺序下载图像?

【问题讨论】:

  • 为什么不使用响应头来设置你写入磁盘的文件的日期?
  • 你为什么关心下载完成的顺序?如果您希望能够将完成的下载与原始链接相关联,可以在回调范围内的link 中找到。

标签: javascript node.js async.js


【解决方案1】:

看看这个:Creating a promise chain in a for loop

您的图像下载器使用 JS Promises 来下载图像,因此您要做的不是调用 3 个 Promise,而是希望使用 for 循环链接 Promise。为此,请按照 Stack Overflow 答案中的示例,放弃您的 .forEach 循环,改用常规的 for 循环。

【讨论】:

    【解决方案2】:

    使用 async/await 同步循环遍历您的列表,并使用以下函数来执行此操作

    编辑:使用 async/await 或在使用 javascript 时使用 Promise.all 以不阻塞 javascript 事件循环。

    const asyncForEach = async (array, callback) => {
      for (let index = 0; index < array.length; index++) {
        await callback(array[index], index, array)
      }
    }
    
    var options = {
      url: "",
      dest: links.dest,
    }
    
    // use it like so:
    await asyncForEach(links.url, async link => {
      try {
        options.url = link
        const result = await download.image(options)
        console.log("Image downloaded", result)
      } catch (err) {
        console.error(err)
      }
    })
    

    【讨论】:

      【解决方案3】:

      使用Promise.all - 当一个promise 数组中的每个promise 解析时,它都会解析,并返回一个包含所有结果的数组以原始顺序!我建议您避免在此处使用for 循环,因为这样可以更有效地并行下载图像时,将连续下载图像!

      let download = require('image-downloader');
      let links = require('./links.json');
      
      let options = { url: '', dest: links.dest };
      
      let allLinksDownloadedPromise = Promise.all(links.url.map(link => {
        return download.image({ ...options, link });
      }));
      
      allLinksDownloadedPromise.then(arrayOfDownloads => console.log('Downloaded:', arrayOfDownloads));
      

      【讨论】:

        【解决方案4】:

        使用for-loopasync/await 语法使其变得简单。

        const download = require('image-downloader');
        const links = require('./links.json');
        
        (async () => { // `await` can only be used inside an async function.
          try {
            for (const url of links.url) {
              // wait until downloading process finish then continue to solve next url
              const result = await download.image({ url, dest: links.dest });
              console.log("Image downloaded", result);
            }
            console.log("Done!");
          } catch(error) {
            console.log("downloaded error", error)
          }
        })();
        

        【讨论】:

          猜你喜欢
          • 2019-10-09
          • 2019-06-10
          • 2013-04-11
          • 2021-01-08
          • 1970-01-01
          • 2020-01-07
          • 2018-07-17
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多